From ea31e7b17661bf017f430b5e34935e88d0b0d5eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Fri, 12 May 2023 10:37:45 +0200 Subject: [PATCH 01/41] Change concordium-base dep URL to relative to allow ssh git modules --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 3ef8d0e6e..08ac4a26c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "deps/concordium-base"] path = deps/concordium-base - url = https://github.com/Concordium/concordium-base.git + url = ../concordium-base.git From 17156c2cacd00798ba7a9aa4650f98d1fc5dd518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Fri, 12 May 2023 10:38:58 +0200 Subject: [PATCH 02/41] Correct wrong error message --- packages/rust-bindings/src/external_functions.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rust-bindings/src/external_functions.rs b/packages/rust-bindings/src/external_functions.rs index e5adaf715..e98db0752 100644 --- a/packages/rust-bindings/src/external_functions.rs +++ b/packages/rust-bindings/src/external_functions.rs @@ -113,7 +113,7 @@ pub fn serialize_receive_contract_parameters( schema_version, ) { Ok(s) => Ok(s), - Err(e) => Err(format!("unable to deserialize parameters, due to: {}", e)), + Err(e) => Err(format!("unable to serialize parameters, due to: {}", e)), } } @@ -127,7 +127,7 @@ pub fn serialize_init_contract_parameters( match serialize_init_contract_parameters_aux(parameters, schema, contract_name, schema_version) { Ok(s) => Ok(s), - Err(e) => Err(format!("unable to deserialize parameters, due to: {}", e)), + Err(e) => Err(format!("unable to serialize parameters, due to: {}", e)), } } From 08ed6ff0e2997a7dba39be60c8bf6ced80453af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Fri, 12 May 2023 10:53:23 +0200 Subject: [PATCH 03/41] Fix chrono dependency mismatch --- deps/concordium-base | 2 +- packages/rust-bindings/Cargo.lock | 124 ++++++++++++++++++++++++++++-- 2 files changed, 119 insertions(+), 7 deletions(-) diff --git a/deps/concordium-base b/deps/concordium-base index 4466b3544..637e9de24 160000 --- a/deps/concordium-base +++ b/deps/concordium-base @@ -1 +1 @@ -Subproject commit 4466b354472dce943256e4cb964f1e4131ed5985 +Subproject commit 637e9de246eab182a47abb4d6fd7ea90d8799a53 diff --git a/packages/rust-bindings/Cargo.lock b/packages/rust-bindings/Cargo.lock index 0fb9a6bcd..a8bc14bfd 100644 --- a/packages/rust-bindings/Cargo.lock +++ b/packages/rust-bindings/Cargo.lock @@ -11,6 +11,15 @@ dependencies = [ "memchr", ] +[[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 = "anyhow" version = "1.0.44" @@ -74,6 +83,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "cfg-if" version = "1.0.0" @@ -82,20 +97,22 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ - "libc", + "iana-time-zone", + "js-sys", "num-integer", "num-traits", "time", + "wasm-bindgen", "winapi", ] [[package]] name = "concordium-contracts-common" -version = "5.3.1" +version = "6.0.0" dependencies = [ "bs58", "chrono", @@ -114,7 +131,7 @@ dependencies = [ [[package]] name = "concordium-contracts-common-derive" -version = "1.0.1" +version = "2.0.0" dependencies = [ "proc-macro2", "quote", @@ -140,7 +157,7 @@ dependencies = [ [[package]] name = "concordium_base" -version = "1.0.0" +version = "1.2.0" dependencies = [ "anyhow", "bs58", @@ -190,6 +207,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + [[package]] name = "cpufeatures" version = "0.2.1" @@ -443,6 +466,29 @@ dependencies = [ "digest 0.10.3", ] +[[package]] +name = "iana-time-zone" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", +] + +[[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 = "itertools" version = "0.10.3" @@ -1103,6 +1149,72 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "zeroize" version = "1.4.2" From 834073417fb5cab984d047a20db8d7687583e131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Mon, 15 May 2023 15:49:31 +0200 Subject: [PATCH 04/41] Update ref to concordium-base --- deps/concordium-base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/concordium-base b/deps/concordium-base index 637e9de24..b6079dc27 160000 --- a/deps/concordium-base +++ b/deps/concordium-base @@ -1 +1 @@ -Subproject commit 637e9de246eab182a47abb4d6fd7ea90d8799a53 +Subproject commit b6079dc273ce139facdf663f2a34163ae5b4a304 From e00248920efeebcd63e4116b932286e335468295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Mon, 22 May 2023 11:13:57 +0200 Subject: [PATCH 05/41] Add option to print serialization errors as verbose --- deps/concordium-base | 2 +- packages/common/src/serialization.ts | 18 ++++++---- packages/rust-bindings/src/aux_functions.rs | 36 ++++++++++++++----- .../rust-bindings/src/external_functions.rs | 20 ++++++++--- 4 files changed, 57 insertions(+), 19 deletions(-) diff --git a/deps/concordium-base b/deps/concordium-base index b6079dc27..4a759a62c 160000 --- a/deps/concordium-base +++ b/deps/concordium-base @@ -1 +1 @@ -Subproject commit b6079dc273ce139facdf663f2a34163ae5b4a304 +Subproject commit 4a759a62ced22bd9710135e6682a12d35b79bce8 diff --git a/packages/common/src/serialization.ts b/packages/common/src/serialization.ts index 8be91c1ac..24a1275fe 100644 --- a/packages/common/src/serialization.ts +++ b/packages/common/src/serialization.ts @@ -466,13 +466,15 @@ export function serializeInitContractParameters( // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types parameters: any, rawSchema: Buffer, - schemaVersion?: SchemaVersion + schemaVersion?: SchemaVersion, + verboseErrorMessage = false ): Buffer { const serializedParameters = wasm.serializeInitContractParameters( JSON.stringify(parameters), rawSchema.toString('hex'), contractName, - schemaVersion + schemaVersion, + verboseErrorMessage ); return Buffer.from(serializedParameters, 'hex'); } @@ -491,14 +493,16 @@ export function serializeUpdateContractParameters( // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types parameters: any, rawSchema: Buffer, - schemaVersion?: SchemaVersion + schemaVersion?: SchemaVersion, + verboseErrorMessage = false ): Buffer { const serializedParameters = wasm.serializeReceiveContractParameters( JSON.stringify(parameters), rawSchema.toString('hex'), contractName, receiveFunctionName, - schemaVersion + schemaVersion, + verboseErrorMessage ); return Buffer.from(serializedParameters, 'hex'); } @@ -512,11 +516,13 @@ export function serializeUpdateContractParameters( export function serializeTypeValue( // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types value: any, - rawSchema: Buffer + rawSchema: Buffer, + verboseErrorMessage = false ): Buffer { const serializedValue = wasm.serializeTypeValue( JSON.stringify(value), - rawSchema.toString('hex') + rawSchema.toString('hex'), + verboseErrorMessage ); return Buffer.from(serializedValue, 'hex'); } diff --git a/packages/rust-bindings/src/aux_functions.rs b/packages/rust-bindings/src/aux_functions.rs index 1794c49c7..717f51176 100644 --- a/packages/rust-bindings/src/aux_functions.rs +++ b/packages/rust-bindings/src/aux_functions.rs @@ -627,6 +627,10 @@ pub fn deserialize_init_error_aux( deserialize_type_value(error_bytes, &error_schema) } +#[derive(thiserror::Error, Debug)] +#[error("{0}")] +pub struct SerialError(String); + /// Given parameters to a receive function as a stringified json, serialize them /// using the provided schema. pub fn serialize_receive_contract_parameters_aux( @@ -635,12 +639,15 @@ pub fn serialize_receive_contract_parameters_aux( contract_name: &str, function_name: &str, schema_version: Option, + verbose_error_message: bool, ) -> Result { let module_schema = VersionedModuleSchema::new(&hex::decode(schema)?, &schema_version)?; let parameter_type = module_schema.get_receive_param_schema(contract_name, function_name)?; let value: SerdeValue = serde_json::from_str(¶meters)?; - let buf = parameter_type.serial_value(&value)?; + let buf = parameter_type + .serial_value(&value) + .map_err(|e| SerialError(format!("{}", e.print(verbose_error_message))))?; Ok(hex::encode(buf)) } @@ -652,12 +659,15 @@ pub fn serialize_init_contract_parameters_aux( schema: HexString, contract_name: &str, schema_version: Option, + verbose_error_message: bool, ) -> Result { let module_schema = VersionedModuleSchema::new(&hex::decode(schema)?, &schema_version)?; let parameter_type = module_schema.get_init_param_schema(contract_name)?; let value: SerdeValue = serde_json::from_str(¶meters)?; - let buf = parameter_type.serial_value(&value)?; + let buf = parameter_type + .serial_value(&value) + .map_err(|e| SerialError(format!("{}", e.print(verbose_error_message))))?; Ok(hex::encode(buf)) } @@ -687,15 +697,25 @@ pub fn get_init_contract_parameter_schema_aux( ))) } -pub fn serialize_type_value_aux(parameters: JsonString, schema: HexString) -> Result { +pub fn serialize_type_value_aux( + parameters: JsonString, + schema: HexString, + verbose_error_message: bool, +) -> Result { let parameter_type: Type = from_bytes(&hex::decode(schema)?)?; - serialize_type_value(parameters, parameter_type) + serialize_type_value(parameters, parameter_type, verbose_error_message) } -fn serialize_type_value(raw_value: JsonString, value_type: Type) -> Result { +fn serialize_type_value( + raw_value: JsonString, + value_type: Type, + verbose_error_message: bool, +) -> Result { let value: SerdeValue = serde_json::from_str(&raw_value)?; - let buf = value_type.serial_value(&value)?; + let buf = value_type + .serial_value(&value) + .map_err(|e| SerialError(format!("{}", e.print(verbose_error_message))))?; Ok(hex::encode(buf)) } @@ -711,7 +731,7 @@ fn deserialize_type_value(serialized_value: HexString, value_type: &Type) -> Res let mut cursor = Cursor::new(hex::decode(serialized_value)?); match value_type.to_json(&mut cursor) { Ok(v) => Ok(to_string(&v)?), - Err(_) => Err(anyhow!("Unable to parse value to json.")), + Err(_) => Err(anyhow!("Unable to parse value to json")), } } @@ -781,7 +801,7 @@ pub fn create_id_proof_aux(input: IdProofInput) -> Result { &attribute_list, &credential_context, ) - .context("Unable to generate proof.")?; + .context("Unable to generate proof")?; let out = IdProofOutput { credential: base16_encode_string(&credential), diff --git a/packages/rust-bindings/src/external_functions.rs b/packages/rust-bindings/src/external_functions.rs index e98db0752..0e4f6e7f5 100644 --- a/packages/rust-bindings/src/external_functions.rs +++ b/packages/rust-bindings/src/external_functions.rs @@ -104,6 +104,7 @@ pub fn serialize_receive_contract_parameters( contract_name: &str, function_name: &str, schema_version: Option, + verbose_error_message: Option, ) -> Result { match serialize_receive_contract_parameters_aux( parameters, @@ -111,6 +112,7 @@ pub fn serialize_receive_contract_parameters( contract_name, function_name, schema_version, + verbose_error_message.unwrap_or(false), ) { Ok(s) => Ok(s), Err(e) => Err(format!("unable to serialize parameters, due to: {}", e)), @@ -123,9 +125,15 @@ pub fn serialize_init_contract_parameters( schema: HexString, contract_name: &str, schema_version: Option, + verbose_error_message: Option, ) -> Result { - match serialize_init_contract_parameters_aux(parameters, schema, contract_name, schema_version) - { + match serialize_init_contract_parameters_aux( + parameters, + schema, + contract_name, + schema_version, + verbose_error_message.unwrap_or(false), + ) { Ok(s) => Ok(s), Err(e) => Err(format!("unable to serialize parameters, due to: {}", e)), } @@ -162,8 +170,12 @@ pub fn get_init_contract_parameter_schema_ext( } #[wasm_bindgen(js_name = serializeTypeValue)] -pub fn serialize_type_value_ext(value: JsonString, schema: HexString) -> Result { - serialize_type_value_aux(value, schema) +pub fn serialize_type_value_ext( + value: JsonString, + schema: HexString, + verbose_error_message: Option, +) -> Result { + serialize_type_value_aux(value, schema, verbose_error_message.unwrap_or(false)) .map_err(|e| format!("Unable to serialize value due to: {}", e)) } From 26911a91aed27e6f2c93ab31b6cdb3a06c94ea8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Tue, 23 May 2023 14:27:22 +0200 Subject: [PATCH 06/41] Ensure errors returned from wasm are proper JS errors --- .../rust-bindings/src/external_functions.rs | 244 ++++++++---------- 1 file changed, 106 insertions(+), 138 deletions(-) diff --git a/packages/rust-bindings/src/external_functions.rs b/packages/rust-bindings/src/external_functions.rs index 0e4f6e7f5..d876c445c 100644 --- a/packages/rust-bindings/src/external_functions.rs +++ b/packages/rust-bindings/src/external_functions.rs @@ -1,12 +1,20 @@ +use std::fmt::Display; + use crate::{aux_functions::*, types::*}; use wasm_bindgen::prelude::*; +type JsResult = Result; + +fn to_js_error(error: impl Display) -> JsError { JsError::new(&format!("{}", error)) } + #[wasm_bindgen(js_name = generateUnsignedCredential)] -pub fn generate_unsigned_credential_ext(input: &str) -> JsonString { - match generate_unsigned_credential_aux(input) { - Ok(s) => s, - Err(e) => format!("Unable to generate an unsigned credential due to: {}", e), - } +pub fn generate_unsigned_credential_ext(input: &str) -> JsResult { + generate_unsigned_credential_aux(input).map_err(|e| { + JsError::new(&format!( + "Unable to generate an unsigned credential due to: {}", + e + )) + }) } // Will be deprecated after GRPCv1 is deprecated @@ -15,41 +23,31 @@ pub fn get_credential_deployment_details_ext( signatures: &JsValue, unsigned_info: &str, expiry: u64, -) -> JsonString { +) -> JsResult { let signatures_vec: Vec = signatures.into_serde().unwrap(); - match get_credential_deployment_details_aux(signatures_vec, unsigned_info, expiry) { - Ok(s) => s, - Err(e) => format!("Unable to get credential deployment details due to: {}", e), - } + get_credential_deployment_details_aux(signatures_vec, unsigned_info, expiry).map_err(|e| { + JsError::new(&format!( + "Unable to get credential deployment details due to: {}", + e + )) + }) } #[wasm_bindgen(js_name = getDeploymentInfo)] -pub fn get_credential_deployment_info_ext(signatures: &JsValue, unsigned_info: &str) -> JsonString { +pub fn get_credential_deployment_info_ext(signatures: &JsValue, unsigned_info: &str) -> JsResult { let signatures_vec: Vec = signatures.into_serde().unwrap(); - match get_credential_deployment_info_aux(signatures_vec, unsigned_info) { - Ok(s) => s, - Err(e) => format!("unable to get credential due to: {}", e), - } + get_credential_deployment_info_aux(signatures_vec, unsigned_info) + .map_err(|e| JsError::new(&format!("Unable to get credential due to: {}", e))) } #[wasm_bindgen(js_name = deserializeState)] -pub fn deserialize_state( - contract_name: &str, - state_bytes: HexString, - schema: String, -) -> JsonString { - match deserialize_state_aux(contract_name, state_bytes, schema) { - Ok(s) => s, - Err(e) => format!("{}", e), - } +pub fn deserialize_state(contract_name: &str, state_bytes: HexString, schema: String) -> JsResult { + deserialize_state_aux(contract_name, state_bytes, schema).map_err(to_js_error) } #[wasm_bindgen(js_name = deserializeCredentialDeployment)] -pub fn deserialize_credential_deployment_ext(serialized: JsonString) -> JsonString { - match deserialize_credential_deployment_aux(&serialized) { - Ok(s) => s, - Err(e) => format!("{}", e), - } +pub fn deserialize_credential_deployment_ext(serialized: JsonString) -> JsResult { + deserialize_credential_deployment_aux(&serialized).map_err(to_js_error) } #[wasm_bindgen(js_name = deserializeReceiveReturnValue)] @@ -59,17 +57,15 @@ pub fn deserialize_receive_return_value( contract_name: &str, function_name: &str, schema_version: Option, -) -> JsonString { - match deserialize_receive_return_value_aux( +) -> JsResult { + deserialize_receive_return_value_aux( return_value_bytes, module_schema, contract_name, function_name, schema_version, - ) { - Ok(s) => s, - Err(e) => format!("{}", e), - } + ) + .map_err(to_js_error) } #[wasm_bindgen(js_name = deserializeReceiveError)] @@ -78,11 +74,9 @@ pub fn deserialize_receive_error( schema: HexString, contract_name: &str, function_name: &str, -) -> JsonString { - match deserialize_receive_error_aux(error_bytes, schema, contract_name, function_name) { - Ok(s) => s, - Err(e) => format!("{}", e), - } +) -> JsResult { + deserialize_receive_error_aux(error_bytes, schema, contract_name, function_name) + .map_err(to_js_error) } #[wasm_bindgen(js_name = deserializeInitError)] @@ -90,11 +84,8 @@ pub fn deserialize_init_error( error_bytes: HexString, schema: HexString, contract_name: &str, -) -> JsonString { - match deserialize_init_error_aux(error_bytes, schema, contract_name) { - Ok(s) => s, - Err(e) => format!("{}", e), - } +) -> JsResult { + deserialize_init_error_aux(error_bytes, schema, contract_name).map_err(to_js_error) } #[wasm_bindgen(js_name = serializeReceiveContractParameters)] @@ -105,18 +96,16 @@ pub fn serialize_receive_contract_parameters( function_name: &str, schema_version: Option, verbose_error_message: Option, -) -> Result { - match serialize_receive_contract_parameters_aux( +) -> JsResult { + serialize_receive_contract_parameters_aux( parameters, schema, contract_name, function_name, schema_version, verbose_error_message.unwrap_or(false), - ) { - Ok(s) => Ok(s), - Err(e) => Err(format!("unable to serialize parameters, due to: {}", e)), - } + ) + .map_err(|e| JsError::new(&format!("Unable to serialize parameters, due to: {}", e))) } #[wasm_bindgen(js_name = serializeInitContractParameters)] @@ -126,17 +115,15 @@ pub fn serialize_init_contract_parameters( contract_name: &str, schema_version: Option, verbose_error_message: Option, -) -> Result { - match serialize_init_contract_parameters_aux( +) -> JsResult { + serialize_init_contract_parameters_aux( parameters, schema, contract_name, schema_version, verbose_error_message.unwrap_or(false), - ) { - Ok(s) => Ok(s), - Err(e) => Err(format!("unable to serialize parameters, due to: {}", e)), - } + ) + .map_err(|e| JsError::new(&format!("Unable to serialize parameters, due to: {}", e))) } #[wasm_bindgen(js_name = getReceiveContractParameterSchema)] @@ -145,16 +132,9 @@ pub fn get_receive_contract_parameter_schema_ext( contract_name: &str, function_name: &str, schema_version: Option, -) -> Result { - match get_receive_contract_parameter_schema_aux( - schema, - contract_name, - function_name, - schema_version, - ) { - Ok(v) => Ok(v), - Err(e) => Err(format!("unable to get parameter schema, due to: {}", e)), - } +) -> JsResult { + get_receive_contract_parameter_schema_aux(schema, contract_name, function_name, schema_version) + .map_err(|e| JsError::new(&format!("unable to get parameter schema, due to: {}", e))) } #[wasm_bindgen(js_name = getInitContractParameterSchema)] @@ -162,11 +142,9 @@ pub fn get_init_contract_parameter_schema_ext( schema: HexString, contract_name: &str, schema_version: Option, -) -> Result { - match get_init_contract_parameter_schema_aux(schema, contract_name, schema_version) { - Ok(v) => Ok(v), - Err(e) => Err(format!("unable to get parameter schema, due to: {}", e)), - } +) -> JsResult { + get_init_contract_parameter_schema_aux(schema, contract_name, schema_version) + .map_err(|e| JsError::new(&format!("unable to get parameter schema, due to: {}", e))) } #[wasm_bindgen(js_name = serializeTypeValue)] @@ -174,53 +152,36 @@ pub fn serialize_type_value_ext( value: JsonString, schema: HexString, verbose_error_message: Option, -) -> Result { +) -> JsResult { serialize_type_value_aux(value, schema, verbose_error_message.unwrap_or(false)) - .map_err(|e| format!("Unable to serialize value due to: {}", e)) + .map_err(|e| JsError::new(&format!("Unable to serialize value due to: {}", e))) } #[wasm_bindgen(js_name = createIdRequestV1)] -pub fn create_id_request_v1_ext(input: JsonString) -> JsonString { - match create_id_request_v1_aux(serde_json::from_str(&input).unwrap()) { - Ok(s) => s, - Err(e) => format!("{}", e), - } +pub fn create_id_request_v1_ext(input: JsonString) -> JsResult { + create_id_request_v1_aux(serde_json::from_str(&input).unwrap()).map_err(to_js_error) } #[wasm_bindgen(js_name = createIdentityRecoveryRequest)] -pub fn create_identity_recovery_request_ext(input: JsonString) -> JsonString { - error_to_string(create_identity_recovery_request_aux( - serde_json::from_str(&input).unwrap(), - )) +pub fn create_identity_recovery_request_ext(input: JsonString) -> JsResult { + create_identity_recovery_request_aux(serde_json::from_str(&input).unwrap()).map_err(to_js_error) } #[wasm_bindgen(js_name = createCredentialV1)] -pub fn create_credential_v1_ext(raw_input: JsonString) -> JsonString { - match serde_json::from_str(&raw_input) { - Ok(input) => match create_credential_v1_aux(input) { - Ok(s) => s, - Err(e) => format!("{}", e), - }, - Err(e) => format!("{}", e), - } +pub fn create_credential_v1_ext(raw_input: JsonString) -> JsResult { + let input = serde_json::from_str(&raw_input)?; + create_credential_v1_aux(input).map_err(to_js_error) } #[wasm_bindgen(js_name = createUnsignedCredentialV1)] -pub fn create_unsigned_credential_v1_ext(input: JsonString) -> JsonString { - error_to_string(create_unsigned_credential_v1_aux( - serde_json::from_str(&input).unwrap(), - )) +pub fn create_unsigned_credential_v1_ext(input: JsonString) -> JsResult { + create_unsigned_credential_v1_aux(serde_json::from_str(&input).unwrap()).map_err(to_js_error) } #[wasm_bindgen(js_name = createIdProof)] -pub fn create_id_proof_ext(raw_input: JsonString) -> JsonString { - match serde_json::from_str(&raw_input) { - Ok(input) => match create_id_proof_aux(input) { - Ok(s) => s, - Err(e) => format!("{}", e), - }, - Err(e) => format!("{}", e), - } +pub fn create_id_proof_ext(raw_input: JsonString) -> JsResult { + let input = serde_json::from_str(&raw_input)?; + create_id_proof_aux(input).map_err(to_js_error) } #[wasm_bindgen(js_name = getAccountSigningKey)] @@ -230,14 +191,15 @@ pub fn get_account_signing_key_ext( identity_provider_index: u32, identity_index: u32, credential_counter: u32, -) -> HexString { - error_to_string(get_account_signing_key_aux( +) -> JsResult { + get_account_signing_key_aux( seed_as_hex, raw_net, identity_provider_index, identity_index, credential_counter, - )) + ) + .map_err(to_js_error) } #[wasm_bindgen(js_name = getAccountPublicKey)] @@ -247,14 +209,15 @@ pub fn get_account_public_key_ext( identity_provider_index: u32, identity_index: u32, credential_counter: u32, -) -> HexString { - error_to_string(get_account_public_key_aux( +) -> JsResult { + get_account_public_key_aux( seed_as_hex, raw_net, identity_provider_index, identity_index, credential_counter, - )) + ) + .map_err(to_js_error) } #[wasm_bindgen(js_name = getCredentialId)] @@ -265,15 +228,16 @@ pub fn get_credential_id_ext( identity_index: u32, credential_counter: u8, raw_on_chain_commitment_key: &str, -) -> HexString { - error_to_string(get_credential_id_aux( +) -> JsResult { + get_credential_id_aux( seed_as_hex, raw_net, identity_provider_index, identity_index, credential_counter, raw_on_chain_commitment_key, - )) + ) + .map_err(to_js_error) } #[wasm_bindgen(js_name = getPrfKey)] @@ -282,13 +246,14 @@ pub fn get_prf_key_ext( raw_net: &str, identity_provider_index: u32, identity_index: u32, -) -> HexString { - error_to_string(get_prf_key_aux( +) -> JsResult { + get_prf_key_aux( seed_as_hex, raw_net, identity_provider_index, identity_index, - )) + ) + .map_err(to_js_error) } #[wasm_bindgen(js_name = getIdCredSec)] @@ -297,13 +262,14 @@ pub fn get_id_cred_sec_ext( raw_net: &str, identity_provider_index: u32, identity_index: u32, -) -> HexString { - error_to_string(get_id_cred_sec_aux( +) -> JsResult { + get_id_cred_sec_aux( seed_as_hex, raw_net, identity_provider_index, identity_index, - )) + ) + .map_err(to_js_error) } #[wasm_bindgen(js_name = getSignatureBlindingRandomness)] @@ -312,13 +278,14 @@ pub fn get_signature_blinding_randomness_ext( raw_net: &str, identity_provider_index: u32, identity_index: u32, -) -> HexString { - error_to_string(get_signature_blinding_randomness_aux( +) -> JsResult { + get_signature_blinding_randomness_aux( seed_as_hex, raw_net, identity_provider_index, identity_index, - )) + ) + .map_err(to_js_error) } #[wasm_bindgen(js_name = getAttributeCommitmentRandomness)] @@ -329,41 +296,42 @@ pub fn get_attribute_commitment_randomness_ext( identity_index: u32, credential_counter: u32, attribute: u8, -) -> HexString { - error_to_string(get_attribute_commitment_randomness_aux( +) -> JsResult { + get_attribute_commitment_randomness_aux( seed_as_hex, raw_net, identity_provider_index, identity_index, credential_counter, attribute, - )) + ) + .map_err(to_js_error) } #[wasm_bindgen(js_name = serializeCredentialDeploymentPayload)] pub fn serialize_credential_deployment_payload_ext( signatures: &JsValue, unsigned_info: &str, -) -> Result, String> { +) -> JsResult> { let signatures_vec: Vec = signatures.into_serde().unwrap(); - serialize_credential_deployment_payload_aux(signatures_vec, unsigned_info) - .map_err(|e| format!("Unable to get credential deployment payload due to: {}", e)) + serialize_credential_deployment_payload_aux(signatures_vec, unsigned_info).map_err(|e| { + JsError::new(&format!( + "Unable to get credential deployment payload due to: {}", + e + )) + }) } #[wasm_bindgen(js_name = generateBakerKeys)] -pub fn generate_baker_keys_ext(sender: Base58String) -> JsonString { - let sender = match sender.parse() { - Ok(sender) => sender, - Err(e) => return format!("unable to parse sender account address: {}.", e), - }; - error_to_string(generate_baker_keys(sender)) +pub fn generate_baker_keys_ext(sender: Base58String) -> JsResult { + let sender = sender + .parse() + .map_err(|e| JsError::new(&format!("Unable to parse sender account address: {}", e)))?; + generate_baker_keys(sender).map_err(to_js_error) } #[wasm_bindgen(js_name = deserializeTypeValue)] -pub fn deserialize_type_value_ext( - serialized_value: HexString, - schema: HexString, -) -> Result { +pub fn deserialize_type_value_ext(serialized_value: HexString, schema: HexString) -> JsResult { deserialize_type_value_aux(serialized_value, schema) - .map_err(|e| format!("Unable to deserialize value due to: {}", e)) + .map_err(|e| JsError::new(&format!("Unable to deserialize value due to: {}", e))) } From d3bd67efcc33935ff4f772a6b6fe823959746b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Tue, 23 May 2023 14:29:10 +0200 Subject: [PATCH 07/41] Update ref to concordium-base --- deps/concordium-base | 2 +- packages/rust-bindings/Cargo.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/concordium-base b/deps/concordium-base index 4a759a62c..b2203032b 160000 --- a/deps/concordium-base +++ b/deps/concordium-base @@ -1 +1 @@ -Subproject commit 4a759a62ced22bd9710135e6682a12d35b79bce8 +Subproject commit b2203032bc09329f5f6614caca67f1b9ba945741 diff --git a/packages/rust-bindings/Cargo.lock b/packages/rust-bindings/Cargo.lock index a8bc14bfd..147ffe256 100644 --- a/packages/rust-bindings/Cargo.lock +++ b/packages/rust-bindings/Cargo.lock @@ -112,7 +112,7 @@ dependencies = [ [[package]] name = "concordium-contracts-common" -version = "6.0.0" +version = "7.0.0" dependencies = [ "bs58", "chrono", From 318ed80370743472f10075171df5b09d50ddb142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Tue, 23 May 2023 14:37:52 +0200 Subject: [PATCH 08/41] Revert contracts-common bump --- deps/concordium-base | 2 +- packages/rust-bindings/Cargo.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/concordium-base b/deps/concordium-base index b2203032b..93fd5fbf3 160000 --- a/deps/concordium-base +++ b/deps/concordium-base @@ -1 +1 @@ -Subproject commit b2203032bc09329f5f6614caca67f1b9ba945741 +Subproject commit 93fd5fbf334f8fc20d77db13662e8ebfd1ac6167 diff --git a/packages/rust-bindings/Cargo.lock b/packages/rust-bindings/Cargo.lock index 147ffe256..a8bc14bfd 100644 --- a/packages/rust-bindings/Cargo.lock +++ b/packages/rust-bindings/Cargo.lock @@ -112,7 +112,7 @@ dependencies = [ [[package]] name = "concordium-contracts-common" -version = "7.0.0" +version = "6.0.0" dependencies = [ "bs58", "chrono", From ad37c495c13318ea3eac0ac623c6db43e474fbea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Tue, 30 May 2023 10:37:29 +0200 Subject: [PATCH 09/41] Update base ref --- deps/concordium-base | 2 +- packages/rust-bindings/src/aux_functions.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/deps/concordium-base b/deps/concordium-base index 93fd5fbf3..274f18867 160000 --- a/deps/concordium-base +++ b/deps/concordium-base @@ -1 +1 @@ -Subproject commit 93fd5fbf334f8fc20d77db13662e8ebfd1ac6167 +Subproject commit 274f18867db435663625b616e409ce26fbcb228c diff --git a/packages/rust-bindings/src/aux_functions.rs b/packages/rust-bindings/src/aux_functions.rs index 717f51176..922a0a974 100644 --- a/packages/rust-bindings/src/aux_functions.rs +++ b/packages/rust-bindings/src/aux_functions.rs @@ -647,7 +647,7 @@ pub fn serialize_receive_contract_parameters_aux( let buf = parameter_type .serial_value(&value) - .map_err(|e| SerialError(format!("{}", e.print(verbose_error_message))))?; + .map_err(|e| SerialError(format!("{}", e.display(verbose_error_message))))?; Ok(hex::encode(buf)) } @@ -667,7 +667,7 @@ pub fn serialize_init_contract_parameters_aux( let buf = parameter_type .serial_value(&value) - .map_err(|e| SerialError(format!("{}", e.print(verbose_error_message))))?; + .map_err(|e| SerialError(format!("{}", e.display(verbose_error_message))))?; Ok(hex::encode(buf)) } @@ -715,7 +715,7 @@ fn serialize_type_value( let buf = value_type .serial_value(&value) - .map_err(|e| SerialError(format!("{}", e.print(verbose_error_message))))?; + .map_err(|e| SerialError(format!("{}", e.display(verbose_error_message))))?; Ok(hex::encode(buf)) } From 987a8433ef944967505336197f6874db7f4c92fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Wed, 31 May 2023 15:31:43 +0200 Subject: [PATCH 10/41] Add option to get verbose error messages when deserializing with schema --- deps/concordium-base | 2 +- packages/rust-bindings/Cargo.lock | 2 +- packages/rust-bindings/src/aux_functions.rs | 115 ++++++++++-------- .../rust-bindings/src/external_functions.rs | 55 +++++++-- 4 files changed, 112 insertions(+), 62 deletions(-) diff --git a/deps/concordium-base b/deps/concordium-base index 274f18867..ed6e2093f 160000 --- a/deps/concordium-base +++ b/deps/concordium-base @@ -1 +1 @@ -Subproject commit 274f18867db435663625b616e409ce26fbcb228c +Subproject commit ed6e2093fbeef6f3513f24774753367cb993207e diff --git a/packages/rust-bindings/Cargo.lock b/packages/rust-bindings/Cargo.lock index a8bc14bfd..cee7333c4 100644 --- a/packages/rust-bindings/Cargo.lock +++ b/packages/rust-bindings/Cargo.lock @@ -521,7 +521,7 @@ checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" [[package]] name = "key_derivation" -version = "1.1.0" +version = "1.2.0" dependencies = [ "concordium_base", "ed25519-dalek", diff --git a/packages/rust-bindings/src/aux_functions.rs b/packages/rust-bindings/src/aux_functions.rs index 922a0a974..4f56bed58 100644 --- a/packages/rust-bindings/src/aux_functions.rs +++ b/packages/rust-bindings/src/aux_functions.rs @@ -52,13 +52,13 @@ pub struct CredId { #[derive(SerdeSerialize, SerdeDeserialize)] #[serde(rename_all = "camelCase")] pub struct IdRequestInput { - ip_info: IpInfo, + ip_info: IpInfo, global_context: GlobalContext, - ars_infos: BTreeMap>, - seed: String, - net: String, + ars_infos: BTreeMap>, + seed: String, + net: String, identity_index: u32, - ar_threshold: u8, + ar_threshold: u8, } pub fn error_to_string(result: Result) -> String { @@ -254,12 +254,12 @@ pub fn create_id_request_v1_aux(input: IdRequestInput) -> Result { #[derive(SerdeSerialize, SerdeDeserialize)] #[serde(rename_all = "camelCase")] pub struct IdRecoveryRequestInput { - ip_info: IpInfo, + ip_info: IpInfo, global_context: GlobalContext, - seed_as_hex: HexString, - net: String, + seed_as_hex: HexString, + net: String, identity_index: u32, - timestamp: u64, + timestamp: u64, } pub fn create_identity_recovery_request_aux(input: IdRecoveryRequestInput) -> Result { @@ -282,16 +282,16 @@ pub fn create_identity_recovery_request_aux(input: IdRecoveryRequestInput) -> Re #[derive(SerdeSerialize, SerdeDeserialize)] #[serde(rename_all = "camelCase")] pub struct CredentialInput { - ip_info: IpInfo, - global_context: GlobalContext, - ars_infos: BTreeMap>, - id_object: IdentityObjectV1, + ip_info: IpInfo, + global_context: GlobalContext, + ars_infos: BTreeMap>, + id_object: IdentityObjectV1, revealed_attributes: Vec, - seed_as_hex: HexString, - net: String, - identity_index: u32, - cred_number: u8, - expiry: TransactionTime, + seed_as_hex: HexString, + net: String, + identity_index: u32, + cred_number: u8, + expiry: TransactionTime, } /// A ConcordiumHdWallet together with an identity index and credential index @@ -299,10 +299,10 @@ pub struct CredentialInput { /// the `create_credential` function due to the implementation of /// `HasAttributeRandomness` below. struct CredentialContext { - wallet: ConcordiumHdWallet, + wallet: ConcordiumHdWallet, identity_provider_index: u32, - identity_index: u32, - credential_index: u32, + identity_index: u32, + credential_index: u32, } impl HasAttributeRandomness for CredentialContext { @@ -420,7 +420,7 @@ pub fn generate_unsigned_credential_aux(input: &str) -> Result { let public_keys: Vec = try_get(&v, "publicKeys")?; let cred_key_info = CredentialPublicKeys { - keys: build_key_map(&public_keys), + keys: build_key_map(&public_keys), threshold: try_get(&v, "threshold")?, }; @@ -516,7 +516,7 @@ pub fn get_credential_deployment_details_aux( let acc_cred = AccountCredential::Normal { cdi }; let credential_message = AccountCredentialMessage { - credential: acc_cred, + credential: acc_cred, message_expiry: TransactionTime { seconds: expiry }, }; @@ -567,6 +567,7 @@ pub fn deserialize_state_aux( contract_name: &str, state_bytes: HexString, schema: HexString, + verbose_error_message: bool, ) -> Result { let module_schema: ModuleV0 = match from_bytes(&hex::decode(schema)?) { Ok(o) => o, @@ -581,7 +582,7 @@ pub fn deserialize_state_aux( .as_ref() .ok_or_else(|| anyhow!("Unable to get state schema: not included in contract schema"))?; - deserialize_type_value(state_bytes, state_schema) + deserialize_type_value(state_bytes, state_schema, verbose_error_message) } /// Given the bytes of a receive function's return value, deserialize them to a @@ -592,12 +593,17 @@ pub fn deserialize_receive_return_value_aux( contract_name: &str, function_name: &str, schema_version: Option, + verbose_error_message: bool, ) -> Result { let module_schema = VersionedModuleSchema::new(&hex::decode(schema)?, &schema_version)?; let return_value_schema = module_schema.get_receive_return_value_schema(contract_name, function_name)?; - deserialize_type_value(return_value_bytes, &return_value_schema) + deserialize_type_value( + return_value_bytes, + &return_value_schema, + verbose_error_message, + ) } /// Given the bytes of a receive function's error, deserialize them to a json @@ -607,11 +613,12 @@ pub fn deserialize_receive_error_aux( schema: HexString, contract_name: &str, function_name: &str, + verbose_error_message: bool, ) -> Result { let module_schema = VersionedModuleSchema::new(&hex::decode(schema)?, &None)?; let error_schema = module_schema.get_receive_error_schema(contract_name, function_name)?; - deserialize_type_value(error_bytes, &error_schema) + deserialize_type_value(error_bytes, &error_schema, verbose_error_message) } /// Given the bytes of an init function's error, deserialize them to a json @@ -620,11 +627,12 @@ pub fn deserialize_init_error_aux( error_bytes: HexString, schema: HexString, contract_name: &str, + verbose_error_message: bool, ) -> Result { let module_schema = VersionedModuleSchema::new(&hex::decode(schema)?, &None)?; let error_schema = module_schema.get_init_error_schema(contract_name)?; - deserialize_type_value(error_bytes, &error_schema) + deserialize_type_value(error_bytes, &error_schema, verbose_error_message) } #[derive(thiserror::Error, Debug)] @@ -722,16 +730,21 @@ fn serialize_type_value( pub fn deserialize_type_value_aux( serialized_value: HexString, schema: HexString, + verbose_error_message: bool, ) -> Result { let value_type: Type = from_bytes(&hex::decode(schema)?)?; - deserialize_type_value(serialized_value, &value_type) + deserialize_type_value(serialized_value, &value_type, verbose_error_message) } -fn deserialize_type_value(serialized_value: HexString, value_type: &Type) -> Result { +fn deserialize_type_value( + serialized_value: HexString, + value_type: &Type, + verbose_error_message: bool, +) -> Result { let mut cursor = Cursor::new(hex::decode(serialized_value)?); match value_type.to_json(&mut cursor) { Ok(v) => Ok(to_string(&v)?), - Err(_) => Err(anyhow!("Unable to parse value to json")), + Err(e) => Err(anyhow!("{}", e.display(verbose_error_message))), } } @@ -739,20 +752,20 @@ fn deserialize_type_value(serialized_value: HexString, value_type: &Type) -> Res #[serde(rename_all = "camelCase")] pub struct IdProofInput { id_object: IdentityObjectV1, - global_context: GlobalContext, - seed_as_hex: String, - net: String, + global_context: GlobalContext, + seed_as_hex: String, + net: String, identity_provider_index: u32, - identity_index: u32, - cred_number: u8, - statement: Statement, - challenge: String, + identity_index: u32, + cred_number: u8, + statement: Statement, + challenge: String, } #[derive(SerdeSerialize, SerdeDeserialize)] struct IdProofOutput { credential: String, - proof: Versioned>, + proof: Versioned>, } pub fn create_id_proof_aux(input: IdProofInput) -> Result { @@ -805,7 +818,7 @@ pub fn create_id_proof_aux(input: IdProofInput) -> Result { let out = IdProofOutput { credential: base16_encode_string(&credential), - proof: Versioned::new(VERSION_0, proof), + proof: Versioned::new(VERSION_0, proof), }; Ok(json!(out).to_string()) @@ -828,17 +841,17 @@ pub fn serialize_credential_deployment_payload_aux( #[derive(SerdeSerialize, SerdeDeserialize)] #[serde(rename_all = "camelCase")] pub struct UnsignedCredentialInput { - ip_info: IpInfo, - global_context: GlobalContext, - ars_infos: BTreeMap>, + ip_info: IpInfo, + global_context: GlobalContext, + ars_infos: BTreeMap>, id_object: IdentityObjectV1, - id_cred_sec: PedersenValue, - prf_key: prf::SecretKey, + id_cred_sec: PedersenValue, + prf_key: prf::SecretKey, sig_retrievel_randomness: String, - credential_public_keys: CredentialPublicKeys, - attribute_randomness: BTreeMap>, - revealed_attributes: Vec, - cred_number: u8, + credential_public_keys: CredentialPublicKeys, + attribute_randomness: BTreeMap>, + revealed_attributes: Vec, + cred_number: u8, } struct AttributeRandomness(BTreeMap>); @@ -871,7 +884,7 @@ pub fn create_unsigned_credential_v1_aux(input: UnsignedCredentialInput) -> Resu }; let aci = AccCredentialInfo { cred_holder_info: chi, - prf_key: input.prf_key, + prf_key: input.prf_key, }; let blinding_randomness: Value = concordium_base::common::from_bytes( @@ -909,11 +922,11 @@ pub fn create_unsigned_credential_v1_aux(input: UnsignedCredentialInput) -> Resu #[serde(rename_all = "camelCase")] pub struct BakerKeys { #[serde(flatten)] - keys_payload: ConfigureBakerKeysPayload, + keys_payload: ConfigureBakerKeysPayload, #[serde(serialize_with = "base16_encode", rename = "electionPrivateKey")] election_private_key: BakerElectionSignKey, #[serde(serialize_with = "base16_encode", rename = "signatureSignKey")] - signature_sign_key: BakerSignatureSignKey, + signature_sign_key: BakerSignatureSignKey, #[serde(serialize_with = "base16_encode", rename = "aggregationSignKey")] aggregation_sign_key: BakerAggregationSignKey, } diff --git a/packages/rust-bindings/src/external_functions.rs b/packages/rust-bindings/src/external_functions.rs index d876c445c..86ee48fde 100644 --- a/packages/rust-bindings/src/external_functions.rs +++ b/packages/rust-bindings/src/external_functions.rs @@ -5,7 +5,9 @@ use wasm_bindgen::prelude::*; type JsResult = Result; -fn to_js_error(error: impl Display) -> JsError { JsError::new(&format!("{}", error)) } +fn to_js_error(error: impl Display) -> JsError { + JsError::new(&format!("{}", error)) +} #[wasm_bindgen(js_name = generateUnsignedCredential)] pub fn generate_unsigned_credential_ext(input: &str) -> JsResult { @@ -41,8 +43,19 @@ pub fn get_credential_deployment_info_ext(signatures: &JsValue, unsigned_info: & } #[wasm_bindgen(js_name = deserializeState)] -pub fn deserialize_state(contract_name: &str, state_bytes: HexString, schema: String) -> JsResult { - deserialize_state_aux(contract_name, state_bytes, schema).map_err(to_js_error) +pub fn deserialize_state( + contract_name: &str, + state_bytes: HexString, + schema: String, + verbose_error_message: Option, +) -> JsResult { + deserialize_state_aux( + contract_name, + state_bytes, + schema, + verbose_error_message.unwrap_or(false), + ) + .map_err(to_js_error) } #[wasm_bindgen(js_name = deserializeCredentialDeployment)] @@ -57,6 +70,7 @@ pub fn deserialize_receive_return_value( contract_name: &str, function_name: &str, schema_version: Option, + verbose_error_message: Option, ) -> JsResult { deserialize_receive_return_value_aux( return_value_bytes, @@ -64,6 +78,7 @@ pub fn deserialize_receive_return_value( contract_name, function_name, schema_version, + verbose_error_message.unwrap_or(false), ) .map_err(to_js_error) } @@ -74,9 +89,16 @@ pub fn deserialize_receive_error( schema: HexString, contract_name: &str, function_name: &str, + verbose_error_message: Option, ) -> JsResult { - deserialize_receive_error_aux(error_bytes, schema, contract_name, function_name) - .map_err(to_js_error) + deserialize_receive_error_aux( + error_bytes, + schema, + contract_name, + function_name, + verbose_error_message.unwrap_or(false), + ) + .map_err(to_js_error) } #[wasm_bindgen(js_name = deserializeInitError)] @@ -84,8 +106,15 @@ pub fn deserialize_init_error( error_bytes: HexString, schema: HexString, contract_name: &str, + verbose_error_message: Option, ) -> JsResult { - deserialize_init_error_aux(error_bytes, schema, contract_name).map_err(to_js_error) + deserialize_init_error_aux( + error_bytes, + schema, + contract_name, + verbose_error_message.unwrap_or(false), + ) + .map_err(to_js_error) } #[wasm_bindgen(js_name = serializeReceiveContractParameters)] @@ -331,7 +360,15 @@ pub fn generate_baker_keys_ext(sender: Base58String) -> JsResult { } #[wasm_bindgen(js_name = deserializeTypeValue)] -pub fn deserialize_type_value_ext(serialized_value: HexString, schema: HexString) -> JsResult { - deserialize_type_value_aux(serialized_value, schema) - .map_err(|e| JsError::new(&format!("Unable to deserialize value due to: {}", e))) +pub fn deserialize_type_value_ext( + serialized_value: HexString, + schema: HexString, + verbose_error_message: Option, +) -> JsResult { + deserialize_type_value_aux( + serialized_value, + schema, + verbose_error_message.unwrap_or(false), + ) + .map_err(|e| JsError::new(&format!("Unable to deserialize value due to: {}", e))) } From 254bee5329971fe16a78442be199d377006d06be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 1 Jun 2023 08:26:31 +0200 Subject: [PATCH 11/41] Add option for verbose deserialization error messages in functions exported from common --- packages/common/src/deserialization.ts | 24 +++-- packages/rust-bindings/src/aux_functions.rs | 88 +++++++++---------- .../rust-bindings/src/external_functions.rs | 4 +- 3 files changed, 61 insertions(+), 55 deletions(-) diff --git a/packages/common/src/deserialization.ts b/packages/common/src/deserialization.ts index d699ceaa2..22dd48993 100644 --- a/packages/common/src/deserialization.ts +++ b/packages/common/src/deserialization.ts @@ -227,7 +227,8 @@ export function deserializeReceiveReturnValue( moduleSchema: Buffer, contractName: string, functionName: string, - schemaVersion?: number + schemaVersion?: number, + verboseErrorMessage = false // eslint-disable-next-line @typescript-eslint/no-explicit-any ): any { const deserializedReturnValue = wasm.deserializeReceiveReturnValue( @@ -235,7 +236,8 @@ export function deserializeReceiveReturnValue( moduleSchema.toString('hex'), contractName, functionName, - schemaVersion + schemaVersion, + verboseErrorMessage ); try { return JSON.parse(deserializedReturnValue); @@ -258,14 +260,16 @@ export function deserializeReceiveError( errorBytes: Buffer, moduleSchema: Buffer, contractName: string, - functionName: string + functionName: string, + verboseErrorMessage = false // eslint-disable-next-line @typescript-eslint/no-explicit-any ): any { const deserializedError = wasm.deserializeReceiveError( errorBytes.toString('hex'), moduleSchema.toString('hex'), contractName, - functionName + functionName, + verboseErrorMessage ); try { return JSON.parse(deserializedError); @@ -286,13 +290,15 @@ export function deserializeReceiveError( export function deserializeInitError( errorBytes: Buffer, moduleSchema: Buffer, - contractName: string + contractName: string, + verboseErrorMessage = false // eslint-disable-next-line @typescript-eslint/no-explicit-any ): any { const deserializedError = wasm.deserializeInitError( errorBytes.toString('hex'), moduleSchema.toString('hex'), - contractName + contractName, + verboseErrorMessage ); try { return JSON.parse(deserializedError); @@ -312,11 +318,13 @@ export function deserializeInitError( */ export function deserializeTypeValue( value: Buffer, - rawSchema: Buffer + rawSchema: Buffer, + verboseErrorMessage = false ): SmartContractTypeValues { const deserializedValue = wasm.deserializeTypeValue( value.toString('hex'), - rawSchema.toString('hex') + rawSchema.toString('hex'), + verboseErrorMessage ); return JSON.parse(deserializedValue); } diff --git a/packages/rust-bindings/src/aux_functions.rs b/packages/rust-bindings/src/aux_functions.rs index 96d358245..b1cf950c4 100644 --- a/packages/rust-bindings/src/aux_functions.rs +++ b/packages/rust-bindings/src/aux_functions.rs @@ -52,13 +52,13 @@ pub struct CredId { #[derive(SerdeSerialize, SerdeDeserialize)] #[serde(rename_all = "camelCase")] pub struct IdRequestInput { - ip_info: IpInfo, + ip_info: IpInfo, global_context: GlobalContext, - ars_infos: BTreeMap>, - seed: String, - net: String, + ars_infos: BTreeMap>, + seed: String, + net: String, identity_index: u32, - ar_threshold: u8, + ar_threshold: u8, } pub fn error_to_string(result: Result) -> String { @@ -284,12 +284,12 @@ pub fn create_id_request_v1_aux(input: IdRequestInput) -> Result { #[derive(SerdeSerialize, SerdeDeserialize)] #[serde(rename_all = "camelCase")] pub struct IdRecoveryRequestInput { - ip_info: IpInfo, + ip_info: IpInfo, global_context: GlobalContext, - seed_as_hex: HexString, - net: String, + seed_as_hex: HexString, + net: String, identity_index: u32, - timestamp: u64, + timestamp: u64, } pub fn create_identity_recovery_request_aux(input: IdRecoveryRequestInput) -> Result { @@ -312,16 +312,16 @@ pub fn create_identity_recovery_request_aux(input: IdRecoveryRequestInput) -> Re #[derive(SerdeSerialize, SerdeDeserialize)] #[serde(rename_all = "camelCase")] pub struct CredentialInput { - ip_info: IpInfo, - global_context: GlobalContext, - ars_infos: BTreeMap>, - id_object: IdentityObjectV1, + ip_info: IpInfo, + global_context: GlobalContext, + ars_infos: BTreeMap>, + id_object: IdentityObjectV1, revealed_attributes: Vec, - seed_as_hex: HexString, - net: String, - identity_index: u32, - cred_number: u8, - expiry: TransactionTime, + seed_as_hex: HexString, + net: String, + identity_index: u32, + cred_number: u8, + expiry: TransactionTime, } /// A ConcordiumHdWallet together with an identity index and credential index @@ -329,10 +329,10 @@ pub struct CredentialInput { /// the `create_credential` function due to the implementation of /// `HasAttributeRandomness` below. struct CredentialContext { - wallet: ConcordiumHdWallet, + wallet: ConcordiumHdWallet, identity_provider_index: u32, - identity_index: u32, - credential_index: u32, + identity_index: u32, + credential_index: u32, } impl HasAttributeRandomness for CredentialContext { @@ -450,7 +450,7 @@ pub fn generate_unsigned_credential_aux(input: &str) -> Result { let public_keys: Vec = try_get(&v, "publicKeys")?; let cred_key_info = CredentialPublicKeys { - keys: build_key_map(&public_keys), + keys: build_key_map(&public_keys), threshold: try_get(&v, "threshold")?, }; @@ -546,7 +546,7 @@ pub fn get_credential_deployment_details_aux( let acc_cred = AccountCredential::Normal { cdi }; let credential_message = AccountCredentialMessage { - credential: acc_cred, + credential: acc_cred, message_expiry: TransactionTime { seconds: expiry }, }; @@ -782,20 +782,20 @@ fn deserialize_type_value( #[serde(rename_all = "camelCase")] pub struct IdProofInput { id_object: IdentityObjectV1, - global_context: GlobalContext, - seed_as_hex: String, - net: String, + global_context: GlobalContext, + seed_as_hex: String, + net: String, identity_provider_index: u32, - identity_index: u32, - cred_number: u8, - statement: Statement, - challenge: String, + identity_index: u32, + cred_number: u8, + statement: Statement, + challenge: String, } #[derive(SerdeSerialize, SerdeDeserialize)] struct IdProofOutput { credential: String, - proof: Versioned>, + proof: Versioned>, } pub fn create_id_proof_aux(input: IdProofInput) -> Result { @@ -848,7 +848,7 @@ pub fn create_id_proof_aux(input: IdProofInput) -> Result { let out = IdProofOutput { credential: base16_encode_string(&credential), - proof: Versioned::new(VERSION_0, proof), + proof: Versioned::new(VERSION_0, proof), }; Ok(json!(out).to_string()) @@ -871,17 +871,17 @@ pub fn serialize_credential_deployment_payload_aux( #[derive(SerdeSerialize, SerdeDeserialize)] #[serde(rename_all = "camelCase")] pub struct UnsignedCredentialInput { - ip_info: IpInfo, - global_context: GlobalContext, - ars_infos: BTreeMap>, + ip_info: IpInfo, + global_context: GlobalContext, + ars_infos: BTreeMap>, id_object: IdentityObjectV1, - id_cred_sec: PedersenValue, - prf_key: prf::SecretKey, + id_cred_sec: PedersenValue, + prf_key: prf::SecretKey, sig_retrievel_randomness: String, - credential_public_keys: CredentialPublicKeys, - attribute_randomness: BTreeMap>, - revealed_attributes: Vec, - cred_number: u8, + credential_public_keys: CredentialPublicKeys, + attribute_randomness: BTreeMap>, + revealed_attributes: Vec, + cred_number: u8, } struct AttributeRandomness(BTreeMap>); @@ -914,7 +914,7 @@ pub fn create_unsigned_credential_v1_aux(input: UnsignedCredentialInput) -> Resu }; let aci = AccCredentialInfo { cred_holder_info: chi, - prf_key: input.prf_key, + prf_key: input.prf_key, }; let blinding_randomness: Value = concordium_base::common::from_bytes( @@ -952,11 +952,11 @@ pub fn create_unsigned_credential_v1_aux(input: UnsignedCredentialInput) -> Resu #[serde(rename_all = "camelCase")] pub struct BakerKeys { #[serde(flatten)] - keys_payload: ConfigureBakerKeysPayload, + keys_payload: ConfigureBakerKeysPayload, #[serde(serialize_with = "base16_encode", rename = "electionPrivateKey")] election_private_key: BakerElectionSignKey, #[serde(serialize_with = "base16_encode", rename = "signatureSignKey")] - signature_sign_key: BakerSignatureSignKey, + signature_sign_key: BakerSignatureSignKey, #[serde(serialize_with = "base16_encode", rename = "aggregationSignKey")] aggregation_sign_key: BakerAggregationSignKey, } diff --git a/packages/rust-bindings/src/external_functions.rs b/packages/rust-bindings/src/external_functions.rs index 8f963f7f9..1023c2b45 100644 --- a/packages/rust-bindings/src/external_functions.rs +++ b/packages/rust-bindings/src/external_functions.rs @@ -5,9 +5,7 @@ use wasm_bindgen::prelude::*; type JsResult = Result; -fn to_js_error(error: impl Display) -> JsError { - JsError::new(&format!("{}", error)) -} +fn to_js_error(error: impl Display) -> JsError { JsError::new(&format!("{}", error)) } #[wasm_bindgen(js_name = generateUnsignedCredential)] pub fn generate_unsigned_credential_ext(input: &str) -> JsResult { From bfc5f46c530ea802f1525d4da8039adffbf8f5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 1 Jun 2023 08:30:36 +0200 Subject: [PATCH 12/41] Cleanup --- packages/common/src/deserialization.ts | 6 ++-- packages/rust-bindings/src/aux_functions.rs | 10 ++---- .../rust-bindings/src/external_functions.rs | 31 +++++++------------ 3 files changed, 19 insertions(+), 28 deletions(-) diff --git a/packages/common/src/deserialization.ts b/packages/common/src/deserialization.ts index 22dd48993..89c95d80d 100644 --- a/packages/common/src/deserialization.ts +++ b/packages/common/src/deserialization.ts @@ -31,13 +31,15 @@ export function deserializeUint8(source: Readable): number { export function deserializeContractState( contractName: string, schema: Buffer, - state: Buffer + state: Buffer, + verboseErrorMessage = false // eslint-disable-next-line @typescript-eslint/no-explicit-any ): any { const serializedState = wasm.deserializeState( contractName, state.toString('hex'), - schema.toString('hex') + schema.toString('hex'), + verboseErrorMessage ); try { return JSON.parse(serializedState); diff --git a/packages/rust-bindings/src/aux_functions.rs b/packages/rust-bindings/src/aux_functions.rs index b1cf950c4..19cfbee33 100644 --- a/packages/rust-bindings/src/aux_functions.rs +++ b/packages/rust-bindings/src/aux_functions.rs @@ -665,10 +665,6 @@ pub fn deserialize_init_error_aux( deserialize_type_value(error_bytes, &error_schema, verbose_error_message) } -#[derive(thiserror::Error, Debug)] -#[error("{0}")] -pub struct SerialError(String); - /// Given parameters to a receive function as a stringified json, serialize them /// using the provided schema. pub fn serialize_receive_contract_parameters_aux( @@ -685,7 +681,7 @@ pub fn serialize_receive_contract_parameters_aux( let buf = parameter_type .serial_value(&value) - .map_err(|e| SerialError(format!("{}", e.display(verbose_error_message))))?; + .map_err(|e| anyhow!("{}", e.display(verbose_error_message)))?; Ok(hex::encode(buf)) } @@ -705,7 +701,7 @@ pub fn serialize_init_contract_parameters_aux( let buf = parameter_type .serial_value(&value) - .map_err(|e| SerialError(format!("{}", e.display(verbose_error_message))))?; + .map_err(|e| anyhow!("{}", e.display(verbose_error_message)))?; Ok(hex::encode(buf)) } @@ -753,7 +749,7 @@ fn serialize_type_value( let buf = value_type .serial_value(&value) - .map_err(|e| SerialError(format!("{}", e.display(verbose_error_message))))?; + .map_err(|e| anyhow!("{}", e.display(verbose_error_message)))?; Ok(hex::encode(buf)) } diff --git a/packages/rust-bindings/src/external_functions.rs b/packages/rust-bindings/src/external_functions.rs index 1023c2b45..3a823b894 100644 --- a/packages/rust-bindings/src/external_functions.rs +++ b/packages/rust-bindings/src/external_functions.rs @@ -5,7 +5,9 @@ use wasm_bindgen::prelude::*; type JsResult = Result; -fn to_js_error(error: impl Display) -> JsError { JsError::new(&format!("{}", error)) } +fn to_js_error(error: impl Display) -> JsError { + JsError::new(&format!("{}", error)) +} #[wasm_bindgen(js_name = generateUnsignedCredential)] pub fn generate_unsigned_credential_ext(input: &str) -> JsResult { @@ -342,12 +344,9 @@ pub fn get_verifiable_credential_signing_key_ext( seed_as_hex: HexString, raw_net: &str, verifiable_credential_index: u32, -) -> HexString { - error_to_string(get_verifiable_credential_signing_key_aux( - seed_as_hex, - raw_net, - verifiable_credential_index, - )) +) -> JsResult { + get_verifiable_credential_signing_key_aux(seed_as_hex, raw_net, verifiable_credential_index) + .map_err(to_js_error) } #[wasm_bindgen(js_name = getVerifiableCredentialPublicKey)] @@ -355,12 +354,9 @@ pub fn get_verifiable_credential_public_key_ext( seed_as_hex: HexString, raw_net: &str, verifiable_credential_index: u32, -) -> HexString { - error_to_string(get_verifiable_credential_public_key_aux( - seed_as_hex, - raw_net, - verifiable_credential_index, - )) +) -> JsResult { + get_verifiable_credential_public_key_aux(seed_as_hex, raw_net, verifiable_credential_index) + .map_err(to_js_error) } #[wasm_bindgen(js_name = getVerifiableCredentialEncryptionKey)] @@ -368,12 +364,9 @@ pub fn get_verifiable_credential_encryption_key_ext( seed_as_hex: HexString, raw_net: &str, verifiable_credential_index: u32, -) -> HexString { - error_to_string(get_verifiable_credential_encryption_key_aux( - seed_as_hex, - raw_net, - verifiable_credential_index, - )) +) -> JsResult { + get_verifiable_credential_encryption_key_aux(seed_as_hex, raw_net, verifiable_credential_index) + .map_err(to_js_error) } #[wasm_bindgen(js_name = serializeCredentialDeploymentPayload)] From 35b39066c447d9220a8f50e116cb51cf5e1fd809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 1 Jun 2023 08:46:49 +0200 Subject: [PATCH 13/41] Update changelog --- packages/rust-bindings/CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/rust-bindings/CHANGELOG.md b/packages/rust-bindings/CHANGELOG.md index 028b9c713..2e0d891ff 100644 --- a/packages/rust-bindings/CHANGELOG.md +++ b/packages/rust-bindings/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## Unreleased + +### Breaking changes + +- Errors returned from entrypoints in `external_functions.rs` are now proper JS errors. + +### Changes + +- Added an additional parameter to contract schema serialization/deserializtion entrypoints, making it possible to receive errors in a verbose format with added detail. + ## 0.12.0 ### Added From 10913d528111d3bd9b0f927fdd42b62f13ec1e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 1 Jun 2023 08:57:51 +0200 Subject: [PATCH 14/41] Document verbose errors param --- packages/common/CHANGELOG.md | 11 +++++++++++ packages/common/src/deserialization.ts | 9 ++++++--- packages/common/src/serialization.ts | 3 +++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index bf6fce26f..6e3c27af1 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -8,6 +8,17 @@ - A `parseWallet` function to parse wallet export files +### Changed +- The following functions now all have an additional parameter controlling whether errors are in a verbose format or not: + - `deserializeContractState` + - `deserializeReceiveReturnValue` + - `deserializeReceiveError` + - `deserializeInitError` + - `deserializeTypeValue` + - `serializeInitContractParameters` + - `serializeUpdateContractParameters` + - `serializeTypeValue` + ## 7.0.0 2023-05-15 ### Breaking changes diff --git a/packages/common/src/deserialization.ts b/packages/common/src/deserialization.ts index 89c95d80d..369fe8e4b 100644 --- a/packages/common/src/deserialization.ts +++ b/packages/common/src/deserialization.ts @@ -221,8 +221,8 @@ export function deserializeTransaction( * @param moduleSchema The raw module schema as a buffer. * @param contractName The name of the contract where the receive function is located. * @param functionName The name of the receive function which return value you want to deserialize. - * @param schemaVersion The schema version as a number. This parameter is optional, - * if you provide a serialized versioned schema this argument won't be needed. + * @param schemaVersion The schema version as a number. This parameter is optional, if you provide a serialized versioned schema this argument won't be needed. + * @param verboseErrorMessage Whether errors are in a verbose format or not. Defaults to `false`. */ export function deserializeReceiveReturnValue( returnValueBytes: Buffer, @@ -257,6 +257,7 @@ export function deserializeReceiveReturnValue( * @param moduleSchema The raw module schema as a buffer. * @param contractName The name of the contract where the receive function is located. * @param functionName The name of the receive function which error you want to deserialize. + * @param verboseErrorMessage Whether errors are in a verbose format or not. Defaults to `false`. */ export function deserializeReceiveError( errorBytes: Buffer, @@ -285,9 +286,10 @@ export function deserializeReceiveError( /** * Deserializes an init function's error from a sequence of bytes into a json object. - * @param returnValueBytes A buffer containing the error as raw bytes. + * @param errorBytes A buffer containing the error as raw bytes. * @param moduleSchema The raw module schema as a buffer. * @param contractName The name of the init function which error you want to deserialize. + * @param verboseErrorMessage Whether errors are in a verbose format or not. Defaults to `false`. */ export function deserializeInitError( errorBytes: Buffer, @@ -316,6 +318,7 @@ export function deserializeInitError( * Given a binary value for a smart contract type, and the raw schema for that type, deserialize the value into the JSON representation. * @param value the value that should be deserialized. * @param rawSchema the schema for the type that the given value should be deserialized as + * @param verboseErrorMessage Whether errors are in a verbose format or not. Defaults to `false`. * @returns the deserialized value */ export function deserializeTypeValue( diff --git a/packages/common/src/serialization.ts b/packages/common/src/serialization.ts index 24a1275fe..def4867f4 100644 --- a/packages/common/src/serialization.ts +++ b/packages/common/src/serialization.ts @@ -459,6 +459,7 @@ export function serializeCredentialDeploymentTransactionForSubmission( * @param parameters the parameters to be serialized. Should correspond to the JSON representation. * @param rawSchema buffer for the schema of a module that contains the contract * @param schemaVersion the version of the schema provided + * @param verboseErrorMessage Whether errors are in a verbose format or not. Defaults to `false`. * @returns serialized buffer of init contract parameters */ export function serializeInitContractParameters( @@ -485,6 +486,7 @@ export function serializeInitContractParameters( * @param parameters the parameters to be serialized. Should correspond to the JSON representation. * @param rawSchema buffer for the schema of a module that contains the contract * @param schemaVersion the version of the schema provided + * @param verboseErrorMessage Whether errors are in a verbose format or not. Defaults to `false`. * @returns serialized buffer of update contract parameters */ export function serializeUpdateContractParameters( @@ -511,6 +513,7 @@ export function serializeUpdateContractParameters( * Given a value for a smart contract type, and the raw schema for that type, serialize the value into binary format. * @param value the value that should be serialized. Should correspond to the JSON representation * @param rawSchema the schema for the type that the given value should be serialized as + * @param verboseErrorMessage Whether errors are in a verbose format or not. Defaults to `false`. * @returns serialized buffer of the value */ export function serializeTypeValue( From 5e7476c02cc4e8961621b5d4016e60211291e306 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 1 Jun 2023 09:11:36 +0200 Subject: [PATCH 15/41] Update rust version for CI to min required by concordium-base --- .github/workflows/pipeline.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 6ed21ee43..c0fc7bfda 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -1,5 +1,5 @@ name: Build, lint and typecheck examples - + on: # Triggers the workflow on push or pull request events but only for the main branch push: @@ -13,7 +13,7 @@ on: env: NODE_VERSION: 18.16.0 - RUST_VERSION: 1.62 + RUST_VERSION: 1.65 RUST_FMT: nightly-2023-04-01-x86_64-unknown-linux-gnu jobs: @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - with: + with: submodules: "recursive" - uses: actions/setup-node@v3 From ebf2dce35d9d2f1e795bf71223fd4701c3cba7dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 1 Jun 2023 09:15:23 +0200 Subject: [PATCH 16/41] Fix fmt error --- packages/rust-bindings/src/external_functions.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/rust-bindings/src/external_functions.rs b/packages/rust-bindings/src/external_functions.rs index 3a823b894..91941c7f1 100644 --- a/packages/rust-bindings/src/external_functions.rs +++ b/packages/rust-bindings/src/external_functions.rs @@ -5,9 +5,7 @@ use wasm_bindgen::prelude::*; type JsResult = Result; -fn to_js_error(error: impl Display) -> JsError { - JsError::new(&format!("{}", error)) -} +fn to_js_error(error: impl Display) -> JsError { JsError::new(&format!("{}", error)) } #[wasm_bindgen(js_name = generateUnsignedCredential)] pub fn generate_unsigned_credential_ext(input: &str) -> JsResult { From 7c7bfca88620dda12c4d7f68f797fcb9e4705a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Tue, 13 Jun 2023 14:08:23 +0200 Subject: [PATCH 17/41] Test that errors from wasm are properly formatted --- packages/common/test/serialization.test.ts | 4 +++- packages/rust-bindings/CHANGELOG.md | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/common/test/serialization.test.ts b/packages/common/test/serialization.test.ts index 970fada8e..5d4813448 100644 --- a/packages/common/test/serialization.test.ts +++ b/packages/common/test/serialization.test.ts @@ -171,5 +171,7 @@ test('serialize type value and serializeUpdateContractParameters give same resul }); test('serializeTypeValue throws an error if unable to serialize', () => { - expect(() => serializeTypeValue('test', Buffer.alloc(0))).toThrow(); + expect(() => serializeTypeValue('test', Buffer.alloc(0))).toThrowError( + Error + ); }); diff --git a/packages/rust-bindings/CHANGELOG.md b/packages/rust-bindings/CHANGELOG.md index 2e0d891ff..5e2528581 100644 --- a/packages/rust-bindings/CHANGELOG.md +++ b/packages/rust-bindings/CHANGELOG.md @@ -4,7 +4,7 @@ ### Breaking changes -- Errors returned from entrypoints in `external_functions.rs` are now proper JS errors. +- Errors returned from entrypoints in `external_functions.rs` are now proper javascript `Error`s. ### Changes From e89e275330643c78a14f5a5348e82cbbceda802f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Tue, 13 Jun 2023 15:15:40 +0200 Subject: [PATCH 18/41] Bump package versions --- packages/common/CHANGELOG.md | 7 +++++++ packages/common/package.json | 4 ++-- packages/nodejs/CHANGELOG.md | 8 ++++++++ packages/nodejs/package.json | 4 ++-- packages/rust-bindings/CHANGELOG.md | 5 +++-- packages/rust-bindings/package.json | 2 +- packages/web/CHANGELOG.md | 11 ++++++++++- packages/web/package.json | 6 +++--- yarn.lock | 12 ++++++------ 9 files changed, 42 insertions(+), 17 deletions(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 6e3c27af1..debda193e 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 8.0.0 + +### Breaking changes + +- Bumped @concordium/rust-bindings to 1.0.0. (Throws proper `Error`s when execution fails for any WASM entrypoint, with improved error messages) + ### Fixed - Cost calculation for `deployModule` transaction. @@ -9,6 +15,7 @@ - A `parseWallet` function to parse wallet export files ### Changed + - The following functions now all have an additional parameter controlling whether errors are in a verbose format or not: - `deserializeContractState` - `deserializeReceiveReturnValue` diff --git a/packages/common/package.json b/packages/common/package.json index 4b78ad535..e7c5d84d0 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -1,6 +1,6 @@ { "name": "@concordium/common-sdk", - "version": "7.0.1", + "version": "8.0.0", "license": "Apache-2.0", "engines": { "node": ">=14.16.0" @@ -51,7 +51,7 @@ "build-dev": "tsc" }, "dependencies": { - "@concordium/rust-bindings": "0.12.0", + "@concordium/rust-bindings": "1.0.0", "@grpc/grpc-js": "^1.3.4", "@noble/ed25519": "^1.7.1", "@protobuf-ts/runtime-rpc": "^2.8.2", diff --git a/packages/nodejs/CHANGELOG.md b/packages/nodejs/CHANGELOG.md index 96be28bd8..653b4b27b 100644 --- a/packages/nodejs/CHANGELOG.md +++ b/packages/nodejs/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 8.0.0 + +### Breaking changes + +- Bumped @concordium/common-sdk to 8.0.0: + - Properly formed errors thrown by functions wrapping WASM execution (from @concordium/rust-bindings) with more helpful error messages. + - and [more](../common/CHANGELOG.md) + ## 7.0.0 2023-05-15 ### Breaking Changes diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 96fc20d06..af7a2d7f5 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -1,6 +1,6 @@ { "name": "@concordium/node-sdk", - "version": "7.0.0", + "version": "8.0.0", "description": "Helpers for interacting with the Concordium node", "repository": { "type": "git", @@ -60,7 +60,7 @@ "build-dev": "tsc" }, "dependencies": { - "@concordium/common-sdk": "7.0.1", + "@concordium/common-sdk": "8.0.0", "@grpc/grpc-js": "^1.3.4", "@protobuf-ts/grpc-transport": "^2.8.2", "buffer": "^6.0.3", diff --git a/packages/rust-bindings/CHANGELOG.md b/packages/rust-bindings/CHANGELOG.md index 5e2528581..991d0531f 100644 --- a/packages/rust-bindings/CHANGELOG.md +++ b/packages/rust-bindings/CHANGELOG.md @@ -1,13 +1,14 @@ # Changelog -## Unreleased +## 1.0.0 ### Breaking changes -- Errors returned from entrypoints in `external_functions.rs` are now proper javascript `Error`s. +- Errors thrown from entrypoints in `external_functions.rs` are now proper javascript `Error`s. ### Changes +- Updated reference to concordium-base, which improves error messages when serializing/deserializing using smart contract schemas. - Added an additional parameter to contract schema serialization/deserializtion entrypoints, making it possible to receive errors in a verbose format with added detail. ## 0.12.0 diff --git a/packages/rust-bindings/package.json b/packages/rust-bindings/package.json index 2324cba9b..fb80af966 100644 --- a/packages/rust-bindings/package.json +++ b/packages/rust-bindings/package.json @@ -1,6 +1,6 @@ { "name": "@concordium/rust-bindings", - "version": "0.12.0", + "version": "1.0.0", "license": "Apache-2.0", "engines": { "node": ">=14.16.0" diff --git a/packages/web/CHANGELOG.md b/packages/web/CHANGELOG.md index 732039d0b..fafee8697 100644 --- a/packages/web/CHANGELOG.md +++ b/packages/web/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 5.0.0 + +### Breaking changes + +- Bumped @concordium/rust-bindings to 1.0.0. (Throws proper `Error`s when execution fails for any WASM entrypoint, with improved error messages) +- Bumped @concordium/common-sdk to 8.0.0: + - Properly formed errors thrown by functions wrapping WASM execution (from @concordium/rust-bindings) with more helpful error messages. + - and [more](../common/CHANGELOG.md) + ## 4.0.1 2023-05-25 ### Changed @@ -10,8 +19,8 @@ ### Breaking Changes -- Bumped @concordium/common-sdk to 7.0.0: - Bumped @concordium/rust-bindings to 0.12.0. (Adds key derivation for verifiable credentials) +- Bumped @concordium/common-sdk to 7.0.0: - Updated `blockInfo` so that the `bakerId` field is optional, since it will be undefined for genesis blocks. - `waitForTransactionFinalization` now returns a `BlockItemSummaryInBlock` - Added missing version return type in `getModuleSchema`. It now returns an object containing the schema source and version. diff --git a/packages/web/package.json b/packages/web/package.json index 95b652b09..05d3fae94 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,6 +1,6 @@ { "name": "@concordium/web-sdk", - "version": "4.0.1", + "version": "5.0.0", "license": "Apache-2.0", "browser": "lib/concordium.min.js", "types": "lib/index.d.ts", @@ -48,8 +48,8 @@ "webpack-cli": "^4.9.2" }, "dependencies": { - "@concordium/common-sdk": "7.0.1", - "@concordium/rust-bindings": "0.12.0", + "@concordium/common-sdk": "8.0.0", + "@concordium/rust-bindings": "1.0.0", "@grpc/grpc-js": "^1.3.4", "@protobuf-ts/grpcweb-transport": "^2.8.2", "buffer": "^6.0.3", diff --git a/yarn.lock b/yarn.lock index f30e881ef..ab8c69eeb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1312,11 +1312,11 @@ __metadata: languageName: node linkType: hard -"@concordium/common-sdk@7.0.1, @concordium/common-sdk@workspace:packages/common": +"@concordium/common-sdk@8.0.0, @concordium/common-sdk@workspace:packages/common": version: 0.0.0-use.local resolution: "@concordium/common-sdk@workspace:packages/common" dependencies: - "@concordium/rust-bindings": 0.12.0 + "@concordium/rust-bindings": 1.0.0 "@grpc/grpc-js": ^1.3.4 "@noble/ed25519": ^1.7.1 "@protobuf-ts/plugin": 2.8.1 @@ -1375,7 +1375,7 @@ __metadata: version: 0.0.0-use.local resolution: "@concordium/node-sdk@workspace:packages/nodejs" dependencies: - "@concordium/common-sdk": 7.0.1 + "@concordium/common-sdk": 8.0.0 "@grpc/grpc-js": ^1.3.4 "@noble/ed25519": ^1.7.1 "@protobuf-ts/grpc-transport": ^2.8.2 @@ -1404,7 +1404,7 @@ __metadata: languageName: unknown linkType: soft -"@concordium/rust-bindings@0.12.0, @concordium/rust-bindings@workspace:packages/rust-bindings": +"@concordium/rust-bindings@1.0.0, @concordium/rust-bindings@workspace:packages/rust-bindings": version: 0.0.0-use.local resolution: "@concordium/rust-bindings@workspace:packages/rust-bindings" languageName: unknown @@ -1414,8 +1414,8 @@ __metadata: version: 0.0.0-use.local resolution: "@concordium/web-sdk@workspace:packages/web" dependencies: - "@concordium/common-sdk": 7.0.1 - "@concordium/rust-bindings": 0.12.0 + "@concordium/common-sdk": 8.0.0 + "@concordium/rust-bindings": 1.0.0 "@grpc/grpc-js": ^1.3.4 "@protobuf-ts/grpcweb-transport": ^2.8.2 "@typescript-eslint/eslint-plugin": ^4.28.1 From e0f647f979b71af196790735ce817e85eb852bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Tue, 20 Jun 2023 15:07:55 +0200 Subject: [PATCH 19/41] Update types to new GRPC api for PV6 --- deps/concordium-base | 2 +- packages/common/src/GRPCTypeTranslation.ts | 447 ++++++++++++++++----- packages/common/src/blockSummaryHelpers.ts | 9 +- packages/common/src/types.ts | 151 +++++-- packages/common/src/types/chainUpdate.ts | 49 ++- 5 files changed, 520 insertions(+), 138 deletions(-) diff --git a/deps/concordium-base b/deps/concordium-base index d7a0b90be..9d4d2c62f 160000 --- a/deps/concordium-base +++ b/deps/concordium-base @@ -1 +1 @@ -Subproject commit d7a0b90be478dcbc95b771b4b79d8a9befbe2d13 +Subproject commit 9d4d2c62f19e80ca27f5c68cbb96862b03b97219 diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index 71cc45988..35a6e1f5a 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -254,7 +254,6 @@ function translateChainParametersCommon( params: v2.ChainParametersV1 | v2.ChainParametersV0 ): v1.ChainParametersCommon { return { - electionDifficulty: trAmountFraction(params.electionDifficulty?.value), euroPerEnergy: unwrap(params.euroPerEnergy?.value), microGTUPerEuro: unwrap(params.microCcdPerEuro?.value), accountCreationLimit: unwrap(params.accountCreationLimit?.value), @@ -275,18 +274,11 @@ function translateRewardParametersCommon( params: v2.ChainParametersV1 | v2.ChainParametersV0 ): v1.RewardParametersCommon { const feeDistribution = params.transactionFeeDistribution; - const gasRewards = params.gasRewards; return { transactionFeeDistribution: { baker: trAmountFraction(feeDistribution?.baker), gasAccount: trAmountFraction(feeDistribution?.gasAccount), }, - gASRewards: { - baker: trAmountFraction(gasRewards?.baker), - finalizationProof: trAmountFraction(gasRewards?.finalizationProof), - accountCreation: trAmountFraction(gasRewards?.accountCreation), - chainUpdate: trAmountFraction(gasRewards?.chainUpdate), - }, }; } @@ -407,89 +399,218 @@ export function cryptographicParameters( }; } +function trChainParametersV0(v0: v2.ChainParametersV0): v1.ChainParametersV0 { + const common = translateChainParametersCommon(v0); + const commonRewardParameters = translateRewardParametersCommon(v0); + return { + ...common, + ...commonRewardParameters, + electionDifficulty: trAmountFraction(v0.electionDifficulty?.value), + bakerCooldownEpochs: unwrap(v0.bakerCooldownEpochs?.value), + minimumThresholdForBaking: unwrap(v0.minimumThresholdForBaking?.value), + gasRewards: { + baker: trAmountFraction(v0.gasRewards?.baker), + finalizationProof: trAmountFraction( + v0.gasRewards?.finalizationProof + ), + accountCreation: trAmountFraction(v0.gasRewards?.accountCreation), + chainUpdate: trAmountFraction(v0.gasRewards?.chainUpdate), + }, + mintDistribution: { + bakingReward: trAmountFraction(v0.mintDistribution?.bakingReward), + finalizationReward: trAmountFraction( + v0.mintDistribution?.finalizationReward + ), + mintPerSlot: trMintRate(v0.mintDistribution?.mintPerSlot), + }, + }; +} + +function trChainParametersV1( + params: v2.ChainParametersV1 +): v1.ChainParametersV1 { + const common = translateChainParametersCommon(params); + const commonRewardParameters = translateRewardParametersCommon(params); + return { + ...common, + ...commonRewardParameters, + electionDifficulty: trAmountFraction(params.electionDifficulty?.value), + timeParameters: { + rewardPeriodLength: unwrap( + params.timeParameters?.rewardPeriodLength?.value?.value + ), + mintPerPayday: trMintRate(params.timeParameters?.mintPerPayday), + }, + cooldownParameters: { + delegatorCooldown: unwrap( + params.cooldownParameters?.delegatorCooldown?.value + ), + poolOwnerCooldown: unwrap( + params.cooldownParameters?.poolOwnerCooldown?.value + ), + }, + poolParameters: { + passiveFinalizationCommission: trAmountFraction( + params.poolParameters?.passiveFinalizationCommission + ), + passiveBakingCommission: trAmountFraction( + params.poolParameters?.passiveBakingCommission + ), + passiveTransactionCommission: trAmountFraction( + params.poolParameters?.passiveTransactionCommission + ), + finalizationCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.finalization + ), + bakingCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.baking + ), + transactionCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.transaction + ), + minimumEquityCapital: unwrap( + params.poolParameters?.minimumEquityCapital?.value + ), + capitalBound: trAmountFraction( + params.poolParameters?.capitalBound?.value + ), + leverageBound: unwrap(params.poolParameters?.leverageBound?.value), + }, + gasRewards: { + baker: trAmountFraction(params.gasRewards?.baker), + finalizationProof: trAmountFraction( + params.gasRewards?.finalizationProof + ), + accountCreation: trAmountFraction( + params.gasRewards?.accountCreation + ), + chainUpdate: trAmountFraction(params.gasRewards?.chainUpdate), + }, + mintDistribution: { + bakingReward: trAmountFraction( + params.mintDistribution?.bakingReward + ), + finalizationReward: trAmountFraction( + params.mintDistribution?.finalizationReward + ), + }, + }; +} + +function trChainParametersV2( + params: v2.ChainParametersV2 +): v1.ChainParametersV2 { + const common = translateChainParametersCommon(params); + const commonRewardParameters = translateRewardParametersCommon(params); + + return { + ...common, + ...commonRewardParameters, + timeParameters: { + rewardPeriodLength: unwrap( + params.timeParameters?.rewardPeriodLength?.value?.value + ), + mintPerPayday: trMintRate(params.timeParameters?.mintPerPayday), + }, + cooldownParameters: { + delegatorCooldown: unwrap( + params.cooldownParameters?.delegatorCooldown?.value + ), + poolOwnerCooldown: unwrap( + params.cooldownParameters?.poolOwnerCooldown?.value + ), + }, + poolParameters: { + passiveFinalizationCommission: trAmountFraction( + params.poolParameters?.passiveFinalizationCommission + ), + passiveBakingCommission: trAmountFraction( + params.poolParameters?.passiveBakingCommission + ), + passiveTransactionCommission: trAmountFraction( + params.poolParameters?.passiveTransactionCommission + ), + finalizationCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.finalization + ), + bakingCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.baking + ), + transactionCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.transaction + ), + minimumEquityCapital: unwrap( + params.poolParameters?.minimumEquityCapital?.value + ), + capitalBound: trAmountFraction( + params.poolParameters?.capitalBound?.value + ), + leverageBound: unwrap(params.poolParameters?.leverageBound?.value), + }, + gasRewards: { + baker: trAmountFraction(params.gasRewards?.baker), + accountCreation: trAmountFraction( + params.gasRewards?.accountCreation + ), + chainUpdate: trAmountFraction(params.gasRewards?.chainUpdate), + }, + mintDistribution: { + bakingReward: trAmountFraction( + params.mintDistribution?.bakingReward + ), + finalizationReward: trAmountFraction( + params.mintDistribution?.finalizationReward + ), + }, + consensusParameters: { + timeoutParameters: { + timeoutBase: unwrap( + params.consensusParameters?.timeoutParameters?.timeoutBase + ?.value + ), + timeoutDecrease: unwrap( + params.consensusParameters?.timeoutParameters + ?.timeoutDecrease + ), + timeoutIncrease: unwrap( + params.consensusParameters?.timeoutParameters + ?.timeoutIncrease + ), + }, + minBlockTime: unwrap( + params.consensusParameters?.minBlockTime?.value + ), + blockEnergyLimit: unwrap( + params.consensusParameters?.blockEnergyLimit?.value + ), + }, + finalizationCommiteeParameters: { + finalizerRelativeStakeThreshold: trAmountFraction( + params.finalizationCommitteeParameters + ?.finalizerRelativeStakeThreshold + ), + minimumFinalizers: unwrap( + params.finalizationCommitteeParameters?.minimumFinalizers + ), + maximumFinalizers: unwrap( + params.finalizationCommitteeParameters?.maximumFinalizers + ), + }, + }; +} + export function blockChainParameters( params: v2.ChainParameters ): v1.ChainParameters { switch (params.parameters.oneofKind) { + case 'v2': { + return trChainParametersV2(params.parameters.v2); + } case 'v1': { - const common = translateChainParametersCommon(params.parameters.v1); - const v1 = params.parameters.v1; - const commonRewardParameters = translateRewardParametersCommon(v1); - return { - ...common, - rewardPeriodLength: unwrap( - v1.timeParameters?.rewardPeriodLength?.value?.value - ), - mintPerPayday: trMintRate(v1.timeParameters?.mintPerPayday), - delegatorCooldown: unwrap( - v1.cooldownParameters?.delegatorCooldown?.value - ), - poolOwnerCooldown: unwrap( - v1.cooldownParameters?.poolOwnerCooldown?.value - ), - passiveFinalizationCommission: trAmountFraction( - v1.poolParameters?.passiveFinalizationCommission - ), - passiveBakingCommission: trAmountFraction( - v1.poolParameters?.passiveBakingCommission - ), - passiveTransactionCommission: trAmountFraction( - v1.poolParameters?.passiveTransactionCommission - ), - finalizationCommissionRange: translateCommissionRange( - v1.poolParameters?.commissionBounds?.finalization - ), - bakingCommissionRange: translateCommissionRange( - v1.poolParameters?.commissionBounds?.baking - ), - transactionCommissionRange: translateCommissionRange( - v1.poolParameters?.commissionBounds?.transaction - ), - minimumEquityCapital: unwrap( - v1.poolParameters?.minimumEquityCapital?.value - ), - capitalBound: trAmountFraction( - v1.poolParameters?.capitalBound?.value - ), - leverageBound: unwrap(v1.poolParameters?.leverageBound?.value), - rewardParameters: { - ...commonRewardParameters, - mintDistribution: { - bakingReward: trAmountFraction( - v1.mintDistribution?.bakingReward - ), - finalizationReward: trAmountFraction( - v1.mintDistribution?.finalizationReward - ), - }, - }, - }; + return trChainParametersV1(params.parameters.v1); } case 'v0': { - const common = translateChainParametersCommon(params.parameters.v0); - const v0 = params.parameters.v0; - const commonRewardParameters = translateRewardParametersCommon(v0); - return { - ...common, - bakerCooldownEpochs: unwrap(v0.bakerCooldownEpochs?.value), - minimumThresholdForBaking: unwrap( - v0.minimumThresholdForBaking?.value - ), - rewardParameters: { - ...commonRewardParameters, - mintDistribution: { - bakingReward: trAmountFraction( - v0.mintDistribution?.bakingReward - ), - finalizationReward: trAmountFraction( - v0.mintDistribution?.finalizationReward - ), - mintPerSlot: trMintRate( - v0.mintDistribution?.mintPerSlot - ), - }, - }, - }; + return trChainParametersV0(params.parameters.v0); } default: throw new Error('Missing chain parameters'); @@ -570,13 +691,12 @@ export function tokenomicsInfo(info: v2.TokenomicsInfo): v1.RewardStatus { } export function consensusInfo(ci: v2.ConsensusInfo): v1.ConsensusStatus { - return { + const common: v1.ConsensusStatusCommon = { bestBlock: unwrapValToHex(ci.bestBlock), genesisBlock: unwrapValToHex(ci.genesisBlock), currentEraGenesisBlock: unwrapValToHex(ci.currentEraGenesisBlock), lastFinalizedBlock: unwrapValToHex(ci.lastFinalizedBlock), epochDuration: unwrap(ci.epochDuration?.value), - slotDuration: unwrap(ci.slotDuration?.value), bestBlockHeight: unwrap(ci.bestBlockHeight?.value), lastFinalizedBlockHeight: unwrap(ci.lastFinalizedBlockHeight?.value), finalizationCount: BigInt(unwrap(ci.finalizationCount)), @@ -621,6 +741,25 @@ export function consensusInfo(ci: v2.ConsensusInfo): v1.ConsensusStatus { lastFinalizedTime: trTimestamp(ci.lastFinalizedTime), }), }; + + if (ci.protocolVersion < v2.ProtocolVersion.PROTOCOL_VERSION_6) { + const ci0: v1.ConsensusStatusV0 = { + ...common, + slotDuration: unwrap(ci.slotDuration?.value), + }; + + return ci0; + } + + const ci1: v1.ConsensusStatusV1 = { + ...common, + currentTimeoutDuration: unwrap(ci.currentTimeoutDuration?.value), + currentRound: unwrap(ci.currentRound?.value), + currentEpoch: unwrap(ci.currentEpoch?.value), + triggerBlockTime: trTimestamp(ci.triggerBlockTime), + }; + + return ci1; } function trAccountAddress( @@ -1162,12 +1301,25 @@ function trTransactionFeeDistributionUpdate( }; } -function trGasRewardsUpdate(gasRewards: v2.GasRewards): v1.GasRewardsUpdate { +function trGasRewardsUpdate(gasRewards: v2.GasRewards): v1.GasRewardsV0Update { return { updateType: v1.UpdateType.GasRewards, update: { baker: trAmountFraction(gasRewards.baker), + accountCreation: trAmountFraction(gasRewards.accountCreation), + chainUpdate: trAmountFraction(gasRewards.accountCreation), finalizationProof: trAmountFraction(gasRewards.finalizationProof), + }, + }; +} + +function trGasRewardsCpv2Update( + gasRewards: v2.GasRewardsCpv2 +): v1.GasRewardsV1Update { + return { + updateType: v1.UpdateType.GasRewardsCpv2, + update: { + baker: trAmountFraction(gasRewards.baker), accountCreation: trAmountFraction(gasRewards.accountCreation), chainUpdate: trAmountFraction(gasRewards.accountCreation), }, @@ -1264,6 +1416,51 @@ function trTimeParametersCpv1Update( }, }; } + +function trTimeoutParameteresUpdate( + timeout: v2.TimeoutParameters +): v1.TimeoutParametersUpdate { + return { + updateType: v1.UpdateType.TimeoutParameters, + update: { + timeoutBase: unwrap(timeout.timeoutBase?.value), + timeoutDecrease: unwrap(timeout.timeoutDecrease), + timeoutIncrease: unwrap(timeout.timeoutIncrease), + }, + }; +} + +function trMinBlockTimeUpdate(duration: v2.Duration): v1.MinBlockTimeUpdate { + return { + updateType: v1.UpdateType.MinBlockTime, + update: unwrap(duration.value), + }; +} + +function trBlockEnergyLimitUpdate( + energy: v2.Energy +): v1.BlockEnergyLimitUpdate { + return { + updateType: v1.UpdateType.BlockEnergyLimit, + update: unwrap(energy.value), + }; +} + +function trFinalizationCommitteeParametersUpdate( + params: v2.FinalizationCommitteeParameters +): v1.FinalizationCommitteeParametersUpdate { + return { + updateType: v1.UpdateType.FinalizationCommitteeParameters, + update: { + finalizerRelativeStakeThreshold: trAmountFraction( + params.finalizerRelativeStakeThreshold + ), + minimumFinalizers: params.minimumFinalizers, + maximumFinalizers: params.maximumFinalizers, + }, + }; +} + function trMintDistributionCpv0Update( mintDist: v2.MintDistributionCpv0 ): v1.MintDistributionUpdate { @@ -1326,6 +1523,18 @@ export function pendingUpdate( return trMintDistributionCpv0Update(effect.mintDistributionCpv0); case 'mintDistributionCpv1': return trMintDistributionCpv1Update(effect.mintDistributionCpv1); + case 'gasRewardsCpv2': + return trGasRewardsCpv2Update(effect.gasRewardsCpv2); + case 'timeoutParameters': + return trTimeoutParameteresUpdate(effect.timeoutParameters); + case 'minBlockTime': + return trMinBlockTimeUpdate(effect.minBlockTime); + case 'blockEnergyLimit': + return trBlockEnergyLimitUpdate(effect.blockEnergyLimit); + case 'finalizationCommitteeParameters': + return trFinalizationCommitteeParametersUpdate( + effect.finalizationCommitteeParameters + ); case 'rootKeys': return { updateType: v1.UpdateType.HigherLevelKeyUpdate, @@ -1365,8 +1574,7 @@ export function pendingUpdate( case undefined: throw Error('Unexpected missing pending update'); default: - // TODO support new updates - throw Error('Unsupported update: ' + effect.oneofKind); + throw Error(`Unsupported update: ${effect}`); } } @@ -1417,6 +1625,18 @@ function trUpdatePayload( return trMintDistributionCpv1Update( payload.mintDistributionCpv1Update ); + case 'gasRewardsCpv2Update': + return trGasRewardsCpv2Update(payload.gasRewardsCpv2Update); + case 'timeoutParametersUpdate': + return trTimeoutParameteresUpdate(payload.timeoutParametersUpdate); + case 'minBlockTimeUpdate': + return trMinBlockTimeUpdate(payload.minBlockTimeUpdate); + case 'blockEnergyLimitUpdate': + return trBlockEnergyLimitUpdate(payload.blockEnergyLimitUpdate); + case 'finalizationCommitteeParametersUpdate': + return trFinalizationCommitteeParametersUpdate( + payload.finalizationCommitteeParametersUpdate + ); case 'rootUpdate': { const rootUpdate = payload.rootUpdate; const keyUpdate = trKeyUpdate(rootUpdate); @@ -1436,10 +1656,7 @@ function trUpdatePayload( case undefined: throw new Error('Unexpected missing update payload'); default: - // TODO support new updates - throw Error( - 'Unsupported update payload type: ' + payload?.oneofKind - ); + throw Error(`Unsupported update payload type: ${payload}`); } } @@ -1517,7 +1734,7 @@ function trAuthorizationsV0(auths: v2.AuthorizationsV0): v1.AuthorizationsV0 { addIdentityProvider: trAccessStructure(auths.addIdentityProvider), addAnonymityRevoker: trAccessStructure(auths.addAnonymityRevoker), emergency: trAccessStructure(auths.emergency), - electionDifficulty: trAccessStructure(auths.parameterConsensus), + consensus: trAccessStructure(auths.parameterConsensus), euroPerEnergy: trAccessStructure(auths.parameterEuroPerEnergy), foundationAccount: trAccessStructure(auths.parameterFoundationAccount), microGTUPerEuro: trAccessStructure(auths.parameterMicroCCDPerEuro), @@ -2072,14 +2289,13 @@ export function blocksAtHeightResponse( } export function blockInfo(blockInfo: v2.BlockInfo): v1.BlockInfo { - return { + const common: v1.BlockInfoCommon = { blockParent: unwrapValToHex(blockInfo.parentBlock), blockHash: unwrapValToHex(blockInfo.hash), blockStateHash: unwrapValToHex(blockInfo.stateHash), blockLastFinalized: unwrapValToHex(blockInfo.lastFinalizedBlock), blockHeight: unwrap(blockInfo.height?.value), blockBaker: blockInfo.baker?.value, - blockSlot: unwrap(blockInfo.slotNumber?.value), blockArriveTime: trTimestamp(blockInfo.arriveTime), blockReceiveTime: trTimestamp(blockInfo.receiveTime), blockSlotTime: trTimestamp(blockInfo.slotTime), @@ -2089,7 +2305,25 @@ export function blockInfo(blockInfo: v2.BlockInfo): v1.BlockInfo { transactionEnergyCost: unwrap(blockInfo.transactionsEnergyCost?.value), genesisIndex: unwrap(blockInfo.genesisIndex?.value), eraBlockHeight: Number(unwrap(blockInfo.eraBlockHeight?.value)), + protocolVersion: BigInt(blockInfo.protocolVersion), + }; + + if (blockInfo.protocolVersion < v2.ProtocolVersion.PROTOCOL_VERSION_6) { + const bi0: v1.BlockInfoV0 = { + ...common, + blockSlot: unwrap(blockInfo.slotNumber?.value), + }; + + return bi0; + } + + const bi1: v1.BlockInfoV1 = { + ...common, + round: unwrap(blockInfo.round?.value), + epoch: unwrap(blockInfo.epoch?.value), }; + + return bi1; } export function delegatorInfo( @@ -2122,13 +2356,22 @@ function trBakerElectionInfo( } export function electionInfo(electionInfo: v2.ElectionInfo): v1.ElectionInfo { + const common: v1.ElectionInfoCommon = { + electionNonce: unwrapValToHex(electionInfo.electionNonce), + bakerElectionInfo: + electionInfo.bakerElectionInfo.map(trBakerElectionInfo), + }; + + if (electionInfo.electionDifficulty === undefined) { + // election difficulty removed in protocol version 6. + return common; + } + return { + ...common, electionDifficulty: trAmountFraction( electionInfo.electionDifficulty?.value ), - electionNonce: unwrapValToHex(electionInfo.electionNonce), - bakerElectionInfo: - electionInfo.bakerElectionInfo.map(trBakerElectionInfo), }; } @@ -2154,6 +2397,12 @@ export function nextUpdateSequenceNumbers( addIdentityProvider: unwrap(nextNums.addIdentityProvider?.value), cooldownParameters: unwrap(nextNums.cooldownParameters?.value), timeParameters: unwrap(nextNums.timeParameters?.value), + timeoutParameters: unwrap(nextNums.timeoutParameters?.value), + minBlockTime: unwrap(nextNums.minBlockTime?.value), + blockEnergyLimit: unwrap(nextNums.blockEnergyLimit?.value), + finalizationCommiteeParameters: unwrap( + nextNums.finalizationCommitteeParameters?.value + ), }; } diff --git a/packages/common/src/blockSummaryHelpers.ts b/packages/common/src/blockSummaryHelpers.ts index 6577019a2..5ef6e8e67 100644 --- a/packages/common/src/blockSummaryHelpers.ts +++ b/packages/common/src/blockSummaryHelpers.ts @@ -7,6 +7,7 @@ import { ChainParameters, ChainParametersV0, ChainParametersV1, + ChainParametersV2, Keys, KeysV0, KeysV1, @@ -24,13 +25,19 @@ export const isAuthorizationsV1 = (a: Authorizations): a is AuthorizationsV1 => export const isChainParametersV1 = ( cp: ChainParameters ): cp is ChainParametersV1 => - (cp as ChainParametersV1).mintPerPayday !== undefined; + (cp as ChainParametersV1).timeParameters !== undefined && + !isChainParametersV2(cp); export const isChainParametersV0 = ( cp: ChainParameters ): cp is ChainParametersV0 => (cp as ChainParametersV0).minimumThresholdForBaking !== undefined; +export const isChainParametersV2 = ( + cp: ChainParameters +): cp is ChainParametersV2 => + (cp as ChainParametersV2).consensusParameters !== undefined; + export const isKeysV1 = (k: Keys): k is KeysV1 => isAuthorizationsV1(k.level2Keys); diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 29edb8a54..edf610fba 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -284,16 +284,20 @@ export type MintDistributionV1 = MintDistributionCommon; export type MintDistribution = MintDistributionV0 | MintDistributionV1; -export interface GasRewards { +export interface GasRewardsCommon { baker: number; - finalizationProof: number; accountCreation: number; chainUpdate: number; } +export interface GasRewardsV0 extends GasRewardsCommon { + finalizationProof: number; +} + +export type GasRewardsV1 = GasRewardsCommon; + export interface RewardParametersCommon { transactionFeeDistribution: TransactionFeeDistribution; - gASRewards: GasRewards; } /** @@ -301,6 +305,7 @@ export interface RewardParametersCommon { */ export interface RewardParametersV0 extends RewardParametersCommon { mintDistribution: MintDistributionV0; + gasRewards: GasRewardsV0; } /** @@ -308,9 +313,13 @@ export interface RewardParametersV0 extends RewardParametersCommon { */ export interface RewardParametersV1 extends RewardParametersCommon { mintDistribution: MintDistributionV1; + gasRewards: GasRewardsV0; } -export type RewardParameters = RewardParametersV0 | RewardParametersV1; +export interface RewardParametersV2 extends RewardParametersCommon { + mintDistribution: MintDistributionV1; + gasRewards: GasRewardsV1; +} export interface CooldownParametersV0 { bakerCooldownEpochs: Epoch; @@ -345,37 +354,71 @@ export interface TimeParametersV1 { mintPerPayday: number; } +export interface TimeoutParameters { + /** + * In milliseconds. + */ + timeoutBase: Duration; + timeoutIncrease: Ratio; + timeoutDecrease: Ratio; +} + +export interface ConsensusParameters { + timeoutParameters: TimeoutParameters; + minBlockTime: Duration; + blockEnergyLimit: bigint; +} + +export interface FinalizationCommitteeParameters { + minimumFinalizers: number; + maximumFinalizers: number; + finalizerRelativeStakeThreshold: number; +} + export interface ChainParametersCommon { - electionDifficulty: number; euroPerEnergy: ExchangeRate; microGTUPerEuro: ExchangeRate; accountCreationLimit: number; - foundationAccountIndex?: bigint; - foundationAccount?: string; + foundationAccount: string; } /** * Used from protocol version 1-3 */ -export interface ChainParametersV0 - extends ChainParametersCommon, - CooldownParametersV0, - PoolParametersV0 { - rewardParameters: RewardParametersV0; -} +export type ChainParametersV0 = ChainParametersCommon & + CooldownParametersV0 & + PoolParametersV0 & + RewardParametersV0 & { + electionDifficulty: number; + }; /** - * Used from protocol version 4 + * Used from protocol version 4-5 */ -export interface ChainParametersV1 - extends ChainParametersCommon, - CooldownParametersV1, - PoolParametersV1, - TimeParametersV1 { - rewardParameters: RewardParametersV1; -} +export type ChainParametersV1 = ChainParametersCommon & + RewardParametersV1 & { + cooldownParameters: CooldownParametersV1; + timeParameters: TimeParametersV1; + poolParameters: PoolParametersV1; + electionDifficulty: number; + }; + +/** + * Used from protocol version 6 + */ +export type ChainParametersV2 = ChainParametersCommon & + RewardParametersV2 & { + consensusParameters: ConsensusParameters; + cooldownParameters: CooldownParametersV1; + timeParameters: TimeParametersV1; + poolParameters: PoolParametersV1; + finalizationCommiteeParameters: FinalizationCommitteeParameters; + }; -export type ChainParameters = ChainParametersV0 | ChainParametersV1; +export type ChainParameters = + | ChainParametersV0 + | ChainParametersV1 + | ChainParametersV2; export interface Authorization { threshold: number; @@ -395,7 +438,7 @@ interface AuthorizationsCommon { * For protocol version 3 and earlier, this controls the authorization of the bakerStakeThreshold update. */ poolParameters: Authorization; - electionDifficulty: Authorization; + consensus: Authorization; addAnonymityRevoker: Authorization; addIdentityProvider: Authorization; keys: VerifyKey[]; @@ -578,7 +621,7 @@ export interface RewardStatusV1 extends RewardStatusCommon { export type RewardStatus = RewardStatusV0 | RewardStatusV1; export type TokenomicsInfo = RewardStatus; -export interface BlockInfo { +export interface BlockInfoCommon { blockParent: HexString; blockHash: HexString; blockStateHash: HexString; @@ -586,7 +629,6 @@ export interface BlockInfo { blockHeight: bigint; blockBaker?: BakerId; - blockSlot: bigint; blockArriveTime: Date; blockReceiveTime: Date; @@ -600,8 +642,22 @@ export interface BlockInfo { genesisIndex: number; eraBlockHeight: number; + protocolVersion: bigint; +} + +/** Used for protocol version 1-5 */ +export interface BlockInfoV0 extends BlockInfoCommon { + blockSlot: bigint; +} + +/** Used from protocol version 6 */ +export interface BlockInfoV1 extends BlockInfoCommon { + round: bigint; + epoch: bigint; } +export type BlockInfo = BlockInfoV0 | BlockInfoV1; + export interface CommonBlockInfo { hash: HexString; height: bigint; @@ -621,7 +677,7 @@ export type BlocksAtHeightRequest = | AbsoluteBlocksAtHeightRequest | RelativeBlocksAtHeightRequest; -export interface ConsensusStatus { +export interface ConsensusStatusCommon { bestBlock: string; genesisBlock: string; currentEraGenesisBlock: string; @@ -631,10 +687,6 @@ export interface ConsensusStatus { * In milliseconds */ epochDuration: bigint; - /** - * In milliseconds - */ - slotDuration: bigint; bestBlockHeight: bigint; lastFinalizedBlockHeight: bigint; @@ -671,6 +723,30 @@ export interface ConsensusStatus { protocolVersion: bigint; } +/** + * Used for protocol version 1-5 + */ +export interface ConsensusStatusV0 extends ConsensusStatusCommon { + /** + * In milliseconds + */ + slotDuration: bigint; +} + +export interface ConcordiumBFTStatus { + currentTimeoutDuration: bigint; + currentRound: bigint; + currentEpoch: bigint; + triggerBlockTime: Date; +} + +/** + * Used from protocol version 6 + */ +export type ConsensusStatusV1 = ConsensusStatusCommon & ConcordiumBFTStatus; + +export type ConsensusStatus = ConsensusStatusV0 | ConsensusStatusV1; + export interface CryptographicParameters { onChainCommitmentKey: string; bulletproofGenerators: string; @@ -1156,12 +1232,19 @@ export interface BakerElectionInfo { lotteryPower: number; } -export interface ElectionInfo { - electionDifficulty: number; +export interface ElectionInfoCommon { electionNonce: HexString; bakerElectionInfo: BakerElectionInfo[]; } +export interface ElectionInfoV0 extends ElectionInfoCommon { + electionDifficulty: number; +} + +export type ElectionInfoV1 = ElectionInfoCommon; + +export type ElectionInfo = ElectionInfoV0 | ElectionInfoV1; + export interface NextUpdateSequenceNumbers { rootKeys: bigint; level1Keys: bigint; @@ -1179,6 +1262,10 @@ export interface NextUpdateSequenceNumbers { addIdentityProvider: bigint; cooldownParameters: bigint; timeParameters: bigint; + timeoutParameters: bigint; + minBlockTime: bigint; + blockEnergyLimit: bigint; + finalizationCommiteeParameters: bigint; } export type BlockFinalizationSummary = diff --git a/packages/common/src/types/chainUpdate.ts b/packages/common/src/types/chainUpdate.ts index 54c352a7d..d3ec8f0ff 100644 --- a/packages/common/src/types/chainUpdate.ts +++ b/packages/common/src/types/chainUpdate.ts @@ -3,7 +3,12 @@ import { AuthorizationsV0, AuthorizationsV1, Base58String, + Duration, + FinalizationCommitteeParameters, + GasRewardsV0, + GasRewardsV1, HexString, + TimeoutParameters, } from '..'; import type { IpInfo, @@ -12,7 +17,6 @@ import type { ExchangeRate, TransactionFeeDistribution, MintDistribution, - GasRewards, MintRate, CommissionRates, } from '../types'; @@ -47,9 +51,14 @@ export interface TransactionFeeDistributionUpdate { update: TransactionFeeDistribution; } -export interface GasRewardsUpdate { +export interface GasRewardsV0Update { updateType: UpdateType.GasRewards; - update: GasRewards; + update: GasRewardsV0; +} + +export interface GasRewardsV1Update { + updateType: UpdateType.GasRewardsCpv2; + update: GasRewardsV1; } export interface AddAnonymityRevokerUpdate { @@ -87,6 +96,26 @@ export interface BakerStakeThresholdUpdate { update: BakerStakeThreshold; } +export interface TimeoutParametersUpdate { + updateType: UpdateType.TimeoutParameters; + update: TimeoutParameters; +} + +export interface MinBlockTimeUpdate { + updateType: UpdateType.MinBlockTime; + update: Duration; +} + +export interface BlockEnergyLimitUpdate { + updateType: UpdateType.BlockEnergyLimit; + update: bigint; +} + +export interface FinalizationCommitteeParametersUpdate { + updateType: UpdateType.FinalizationCommitteeParameters; + update: FinalizationCommitteeParameters; +} + export interface Level1Update { updateType: UpdateType.Level1; update: KeyUpdate; @@ -114,14 +143,19 @@ export type CommonUpdate = | FoundationAccountUpdate | MintDistributionUpdate | ProtocolUpdate - | GasRewardsUpdate + | GasRewardsV0Update | BakerStakeThresholdUpdate | ElectionDifficultyUpdate | AddAnonymityRevokerUpdate | AddIdentityProviderUpdate | CooldownParametersUpdate | PoolParametersUpdate - | TimeParametersUpdate; + | TimeParametersUpdate + | GasRewardsV1Update + | TimeoutParametersUpdate + | MinBlockTimeUpdate + | BlockEnergyLimitUpdate + | FinalizationCommitteeParametersUpdate; export type UpdateInstructionPayload = CommonUpdate | RootUpdate | Level1Update; @@ -151,6 +185,11 @@ export enum UpdateType { ProtocolUpdate = 'protocolUpdate', BakerStakeThreshold = 'bakerStakeThreshold', Emergency = 'emergency', + GasRewardsCpv2 = 'gasRewardsCpv2', + TimeoutParameters = 'timeoutParameters', + MinBlockTime = 'minBlockTime', + BlockEnergyLimit = 'blockEnergyLimit', + FinalizationCommitteeParameters = 'finalizationCommitteeParameters', } export type KeyUpdate = HigherLevelKeyUpdate | AuthorizationKeysUpdate; From f01b4bf1508edcdf4e9f902c49e746ef3d5f2bd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Tue, 20 Jun 2023 15:09:59 +0200 Subject: [PATCH 20/41] Fix jsonRPC not compiling --- packages/common/src/JsonRpcClient.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/common/src/JsonRpcClient.ts b/packages/common/src/JsonRpcClient.ts index b380f1cf3..3378a65d6 100644 --- a/packages/common/src/JsonRpcClient.ts +++ b/packages/common/src/JsonRpcClient.ts @@ -4,7 +4,7 @@ import { AccountTransaction, AccountTransactionSignature, buildInvoker, - ConsensusStatus, + ConsensusStatusV0, ContractAddress, ContractContext, CryptographicParameters, @@ -130,18 +130,18 @@ export class JsonRpcClient { return this.sendRawTransaction(serializedDetails.toString('base64')); } - async getConsensusStatus(): Promise { + async getConsensusStatus(): Promise { const response = await this.provider.request('getConsensusStatus'); // TODO Avoid code duplication with nodejs client - const datePropertyKeys: (keyof ConsensusStatus)[] = [ + const datePropertyKeys: (keyof ConsensusStatusV0)[] = [ 'blockLastReceivedTime', 'blockLastArrivedTime', 'genesisTime', 'currentEraGenesisTime', 'lastFinalizedTime', ]; - const bigIntPropertyKeys: (keyof ConsensusStatus)[] = [ + const bigIntPropertyKeys: (keyof ConsensusStatusV0)[] = [ 'epochDuration', 'slotDuration', 'bestBlockHeight', @@ -152,7 +152,7 @@ export class JsonRpcClient { 'protocolVersion', ]; - const res = transformJsonResponse( + const res = transformJsonResponse( response, buildJsonResponseReviver(datePropertyKeys, bigIntPropertyKeys), intToStringTransformer(bigIntPropertyKeys) From 7763eca4e6ef0c63b5d26fd894fb891e1d7fccf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Wed, 21 Jun 2023 10:27:39 +0200 Subject: [PATCH 21/41] Add helper functions for determining version of versioned types --- packages/common/CHANGELOG.md | 10 ++ packages/common/src/accountHelpers.ts | 21 ---- packages/common/src/blockSummaryHelpers.ts | 44 +-------- packages/common/src/index.ts | 1 + packages/common/src/types.ts | 5 +- packages/common/src/versionedTypeHelpers.ts | 104 ++++++++++++++++++++ 6 files changed, 120 insertions(+), 65 deletions(-) create mode 100644 packages/common/src/versionedTypeHelpers.ts diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index bf6fce26f..7b465d585 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +### Breaking changes + +- Updated `types.ts` to conform to updated GRPC API, which includes adding more variants to existing types (all new variants take effect from protocol version 6): + - `ChainParametersV2` added to `ChainParameters` + - `BlockInfo` changed to `BlockInfoV0 | BlockInfoV1` + - `ConsensusStatus` changed to `ConsensusStatusV0 | ConsensusStatusV1` + - `ElectionInfo` changed to `ElectionInfoV0 | ElectionInfoV1` + ### Fixed - Cost calculation for `deployModule` transaction. @@ -7,6 +15,8 @@ ### Added - A `parseWallet` function to parse wallet export files +- Helper functions to determine version of versioned types mentioned in "Breaking Changes" have been added. +- Support for new chain update types. ## 7.0.0 2023-05-15 diff --git a/packages/common/src/accountHelpers.ts b/packages/common/src/accountHelpers.ts index 7f44012ab..cd311c1b5 100644 --- a/packages/common/src/accountHelpers.ts +++ b/packages/common/src/accountHelpers.ts @@ -3,14 +3,9 @@ import { AccountAddress } from './types/accountAddress'; import { ReduceStakePendingChange, RemovalPendingChange, - StakePendingChange, - StakePendingChangeV1, AccountInfo, AccountInfoBaker, - AccountInfoBakerV0, - AccountInfoBakerV1, AccountInfoDelegator, - StakePendingChangeV0, GenerateBakerKeysOutput, } from './types'; @@ -22,22 +17,6 @@ export const isDelegatorAccount = ( export const isBakerAccount = (ai: AccountInfo): ai is AccountInfoBaker => (ai as AccountInfoBaker).accountBaker !== undefined; -export const isBakerAccountV1 = (ai: AccountInfo): ai is AccountInfoBakerV1 => - (ai as AccountInfoBakerV1).accountBaker?.bakerPoolInfo !== undefined; - -export const isBakerAccountV0 = (ai: AccountInfo): ai is AccountInfoBakerV0 => - (ai as AccountInfoBakerV1).accountBaker?.bakerPoolInfo === undefined; - -export const isStakePendingChangeV1 = ( - spc: StakePendingChange -): spc is StakePendingChangeV1 => - (spc as StakePendingChangeV1).effectiveTime !== undefined; - -export const isStakePendingChangeV0 = ( - spc: StakePendingChange -): spc is StakePendingChangeV0 => - (spc as StakePendingChangeV0).epoch !== undefined; - export const isReduceStakePendingChange = ( spc: ReduceStakePendingChange | RemovalPendingChange ): spc is ReduceStakePendingChange => diff --git a/packages/common/src/blockSummaryHelpers.ts b/packages/common/src/blockSummaryHelpers.ts index 5ef6e8e67..508be086b 100644 --- a/packages/common/src/blockSummaryHelpers.ts +++ b/packages/common/src/blockSummaryHelpers.ts @@ -1,54 +1,12 @@ import { - Authorizations, - AuthorizationsV1, BlockSummary, BlockSummaryV0, BlockSummaryV1, - ChainParameters, - ChainParametersV0, - ChainParametersV1, - ChainParametersV2, - Keys, - KeysV0, - KeysV1, - UpdateQueues, - UpdateQueuesV0, - UpdateQueuesV1, Updates, UpdatesV0, UpdatesV1, } from './types'; - -export const isAuthorizationsV1 = (a: Authorizations): a is AuthorizationsV1 => - (a as AuthorizationsV1).timeParameters !== undefined; - -export const isChainParametersV1 = ( - cp: ChainParameters -): cp is ChainParametersV1 => - (cp as ChainParametersV1).timeParameters !== undefined && - !isChainParametersV2(cp); - -export const isChainParametersV0 = ( - cp: ChainParameters -): cp is ChainParametersV0 => - (cp as ChainParametersV0).minimumThresholdForBaking !== undefined; - -export const isChainParametersV2 = ( - cp: ChainParameters -): cp is ChainParametersV2 => - (cp as ChainParametersV2).consensusParameters !== undefined; - -export const isKeysV1 = (k: Keys): k is KeysV1 => - isAuthorizationsV1(k.level2Keys); - -export const isKeysV0 = (k: Keys): k is KeysV0 => - !isAuthorizationsV1(k.level2Keys); - -export const isUpdateQueuesV1 = (uq: UpdateQueues): uq is UpdateQueuesV1 => - (uq as UpdateQueuesV1).timeParameters !== undefined; - -export const isUpdateQueuesV0 = (uq: UpdateQueues): uq is UpdateQueuesV0 => - (uq as UpdateQueuesV0).bakerStakeThreshold !== undefined; +import { isUpdateQueuesV0, isUpdateQueuesV1 } from './versionedTypeHelpers'; export const isUpdatesV1 = (u: Updates): u is UpdatesV1 => isUpdateQueuesV1(u.updateQueues); diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index c2d631125..ef0550e90 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -35,6 +35,7 @@ export { export * from './idProofs'; export * from './idProofTypes'; export * from './signHelpers'; +export * from './versionedTypeHelpers'; export * from './accountHelpers'; export * from './blockSummaryHelpers'; export * from './rewardStatusHelpers'; diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index edf610fba..935333293 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -309,13 +309,16 @@ export interface RewardParametersV0 extends RewardParametersCommon { } /** - * Used from protocol version 4 + * Used from protocol version 4-5 */ export interface RewardParametersV1 extends RewardParametersCommon { mintDistribution: MintDistributionV1; gasRewards: GasRewardsV0; } +/** + * Used from protocol version 6 + */ export interface RewardParametersV2 extends RewardParametersCommon { mintDistribution: MintDistributionV1; gasRewards: GasRewardsV1; diff --git a/packages/common/src/versionedTypeHelpers.ts b/packages/common/src/versionedTypeHelpers.ts new file mode 100644 index 000000000..f38d5a00b --- /dev/null +++ b/packages/common/src/versionedTypeHelpers.ts @@ -0,0 +1,104 @@ +import { + AccountInfo, + AccountInfoBakerV0, + AccountInfoBakerV1, + Authorizations, + AuthorizationsV1, + BlockInfo, + BlockInfoV0, + BlockInfoV1, + ChainParameters, + ChainParametersV0, + ChainParametersV1, + ChainParametersV2, + ConsensusStatus, + ConsensusStatusV0, + ConsensusStatusV1, + ElectionInfo, + ElectionInfoV0, + ElectionInfoV1, + Keys, + KeysV0, + KeysV1, + StakePendingChange, + StakePendingChangeV0, + StakePendingChangeV1, + UpdateQueues, + UpdateQueuesV0, + UpdateQueuesV1, +} from './types'; + +export const isBakerAccountV0 = (ai: AccountInfo): ai is AccountInfoBakerV0 => + (ai as AccountInfoBakerV1).accountBaker?.bakerPoolInfo === undefined; + +export const isBakerAccountV1 = (ai: AccountInfo): ai is AccountInfoBakerV1 => + (ai as AccountInfoBakerV1).accountBaker?.bakerPoolInfo !== undefined; + +export const isStakePendingChangeV0 = ( + spc: StakePendingChange +): spc is StakePendingChangeV0 => + (spc as StakePendingChangeV0).epoch !== undefined; + +export const isStakePendingChangeV1 = ( + spc: StakePendingChange +): spc is StakePendingChangeV1 => + (spc as StakePendingChangeV1).effectiveTime !== undefined; + +export const isAuthorizationsV0 = ( + as: Authorizations +): as is AuthorizationsV1 => !isAuthorizationsV1(as); + +export const isAuthorizationsV1 = ( + as: Authorizations +): as is AuthorizationsV1 => + (as as AuthorizationsV1).timeParameters !== undefined; + +export const isChainParametersV0 = ( + cp: ChainParameters +): cp is ChainParametersV0 => + (cp as ChainParametersV0).minimumThresholdForBaking !== undefined; + +export const isChainParametersV1 = ( + cp: ChainParameters +): cp is ChainParametersV1 => + (cp as ChainParametersV1).timeParameters !== undefined && + !isChainParametersV2(cp); + +export const isChainParametersV2 = ( + cp: ChainParameters +): cp is ChainParametersV2 => + (cp as ChainParametersV2).consensusParameters !== undefined; + +export const isKeysV0 = (ks: Keys): ks is KeysV0 => + !isAuthorizationsV1(ks.level2Keys); + +export const isKeysV1 = (ks: Keys): ks is KeysV1 => + isAuthorizationsV1(ks.level2Keys); + +export const isUpdateQueuesV0 = (uq: UpdateQueues): uq is UpdateQueuesV0 => + (uq as UpdateQueuesV0).bakerStakeThreshold !== undefined; + +export const isUpdateQueuesV1 = (uq: UpdateQueues): uq is UpdateQueuesV1 => + (uq as UpdateQueuesV1).timeParameters !== undefined; + +export const isBlockInfoV0 = (bi: BlockInfo): bi is BlockInfoV0 => + (bi as BlockInfoV0).blockSlot !== undefined; + +export const isBlockInfoV1 = (bi: BlockInfo): bi is BlockInfoV1 => + (bi as BlockInfoV1).round !== undefined; + +export const isConsensusStatusV0 = ( + cs: ConsensusStatus +): cs is ConsensusStatusV0 => + (cs as ConsensusStatusV0).slotDuration !== undefined; + +export const isConsensusStatusV1 = ( + cs: ConsensusStatus +): cs is ConsensusStatusV1 => + (cs as ConsensusStatusV1).currentRound !== undefined; + +export const isElectionInfoV0 = (ei: ElectionInfo): ei is ElectionInfoV0 => + (ei as ElectionInfoV0).electionDifficulty !== undefined; + +export const isElectionInfoV1 = (ei: ElectionInfo): ei is ElectionInfoV1 => + !isElectionInfoV0(ei); From 2b4d90bb0be8ae62b0f0ffe8dd1a40981c74c250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Wed, 21 Jun 2023 10:50:53 +0200 Subject: [PATCH 22/41] Update JSON rpc --- packages/common/src/JsonRpcClient.ts | 15 ++- packages/nodejs/src/client.ts | 38 ++++++- packages/rust-bindings/Cargo.lock | 146 ++++++++++++++++++++++++++- 3 files changed, 186 insertions(+), 13 deletions(-) diff --git a/packages/common/src/JsonRpcClient.ts b/packages/common/src/JsonRpcClient.ts index 3378a65d6..0323911cf 100644 --- a/packages/common/src/JsonRpcClient.ts +++ b/packages/common/src/JsonRpcClient.ts @@ -4,7 +4,9 @@ import { AccountTransaction, AccountTransactionSignature, buildInvoker, + ConsensusStatus, ConsensusStatusV0, + ConsensusStatusV1, ContractAddress, ContractContext, CryptographicParameters, @@ -130,18 +132,19 @@ export class JsonRpcClient { return this.sendRawTransaction(serializedDetails.toString('base64')); } - async getConsensusStatus(): Promise { + async getConsensusStatus(): Promise { const response = await this.provider.request('getConsensusStatus'); + type CS = ConsensusStatusV0 & ConsensusStatusV1; // TODO Avoid code duplication with nodejs client - const datePropertyKeys: (keyof ConsensusStatusV0)[] = [ + const datePropertyKeys: (keyof CS)[] = [ 'blockLastReceivedTime', 'blockLastArrivedTime', 'genesisTime', 'currentEraGenesisTime', 'lastFinalizedTime', ]; - const bigIntPropertyKeys: (keyof ConsensusStatusV0)[] = [ + const bigIntPropertyKeys: (keyof CS)[] = [ 'epochDuration', 'slotDuration', 'bestBlockHeight', @@ -150,9 +153,13 @@ export class JsonRpcClient { 'blocksVerifiedCount', 'blocksReceivedCount', 'protocolVersion', + 'currentTimeoutDuration', + 'currentRound', + 'currentEpoch', + 'triggerBlockTime', ]; - const res = transformJsonResponse( + const res = transformJsonResponse( response, buildJsonResponseReviver(datePropertyKeys, bigIntPropertyKeys), intToStringTransformer(bigIntPropertyKeys) diff --git a/packages/nodejs/src/client.ts b/packages/nodejs/src/client.ts index 9256c5050..db3c223ca 100644 --- a/packages/nodejs/src/client.ts +++ b/packages/nodejs/src/client.ts @@ -69,6 +69,17 @@ import { ReduceStakePendingChangeV1, buildInvoker, DelegationStakeChangedEvent, + CooldownParametersV1, + TimeParametersV1, + PoolParametersV1, + BlockInfoV0, + BlockInfoV1, + ConsensusStatusV0, + ConsensusStatusV1, + ChainParametersV2, + ConsensusParameters, + TimeoutParameters, + Ratio, } from '@concordium/common-sdk'; import { buildJsonResponseReviver, @@ -349,13 +360,19 @@ export default class ConcordiumNodeClient { | keyof PartyInfo | keyof FinalizationData | keyof TransactionSummary - | keyof (ChainParametersV0 & ChainParametersV1) + | keyof (ChainParametersV0 & ChainParametersV1 & ChainParametersV2) + | keyof PoolParametersV1 + | keyof CooldownParametersV1 + | keyof TimeParametersV1 | keyof ExchangeRate | keyof UpdateQueue | keyof KeysWithThreshold | keyof TransferredEvent | keyof ContractAddress | keyof DelegationStakeChangedEvent + | keyof ConsensusParameters + | keyof TimeoutParameters + | keyof Ratio )[] = [ 'bakerId', 'newStake', @@ -365,7 +382,6 @@ export default class ConcordiumNodeClient { 'cost', 'energyCost', 'index', - 'foundationAccountIndex', 'numerator', 'denominator', 'nextSequenceNumber', @@ -382,6 +398,13 @@ export default class ConcordiumNodeClient { 'minimumEquityCapital', 'poolOwnerCooldown', 'delegatorCooldown', + + // v2 keys + 'timeoutBase', + 'denominator', + 'numerator', + 'minBlockTime', + 'blockEnergyLimit', ]; return unwrapJsonResponse( @@ -412,7 +435,7 @@ export default class ConcordiumNodeClient { 'blockReceiveTime', 'blockSlotTime', ]; - const bigIntPropertyKeys: (keyof BlockInfo)[] = [ + const bigIntPropertyKeys: (keyof (BlockInfoV0 & BlockInfoV1))[] = [ 'blockHeight', 'blockBaker', 'blockSlot', @@ -460,19 +483,20 @@ export default class ConcordiumNodeClient { * enough data yet. */ async getConsensusStatus(): Promise { + type CS = ConsensusStatusV0 & ConsensusStatusV1; const response = await this.sendRequest( this.client.getConsensusStatus, new Empty() ); - const datePropertyKeys: (keyof ConsensusStatus)[] = [ + const datePropertyKeys: (keyof CS)[] = [ 'blockLastReceivedTime', 'blockLastArrivedTime', 'genesisTime', 'currentEraGenesisTime', 'lastFinalizedTime', ]; - const bigIntPropertyKeys: (keyof ConsensusStatus)[] = [ + const bigIntPropertyKeys: (keyof CS)[] = [ 'epochDuration', 'slotDuration', 'bestBlockHeight', @@ -481,6 +505,10 @@ export default class ConcordiumNodeClient { 'blocksVerifiedCount', 'blocksReceivedCount', 'protocolVersion', + 'currentTimeoutDuration', + 'currentRound', + 'currentEpoch', + 'triggerBlockTime', ]; const consensusStatus = unwrapJsonResponse( diff --git a/packages/rust-bindings/Cargo.lock b/packages/rust-bindings/Cargo.lock index 8dcb4fa95..c2edf7754 100644 --- a/packages/rust-bindings/Cargo.lock +++ b/packages/rust-bindings/Cargo.lock @@ -60,6 +60,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" + [[package]] name = "base64ct" version = "1.0.1" @@ -200,14 +206,15 @@ dependencies = [ "js-sys", "num-integer", "num-traits", - "time", + "serde", + "time 0.1.45", "wasm-bindgen", "winapi", ] [[package]] name = "concordium-contracts-common" -version = "6.0.0" +version = "7.0.0" dependencies = [ "bs58", "chrono", @@ -226,7 +233,7 @@ dependencies = [ [[package]] name = "concordium-contracts-common-derive" -version = "2.0.0" +version = "3.0.0" dependencies = [ "proc-macro2", "quote", @@ -252,7 +259,7 @@ dependencies = [ [[package]] name = "concordium_base" -version = "1.2.0" +version = "2.0.0" dependencies = [ "anyhow", "bs58", @@ -270,6 +277,7 @@ dependencies = [ "itertools", "leb128", "libc", + "nom", "num", "num-bigint 0.4.3", "num-traits", @@ -280,6 +288,7 @@ dependencies = [ "rust_decimal", "serde", "serde_json", + "serde_with", "sha2 0.10.6", "sha3", "subtle", @@ -383,6 +392,41 @@ dependencies = [ "zeroize", ] +[[package]] +name = "darling" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.15", +] + +[[package]] +name = "darling_macro" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.15", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -613,6 +657,23 @@ dependencies = [ "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "itertools" version = "0.10.5" @@ -708,6 +769,22 @@ dependencies = [ "autocfg", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "num" version = "0.4.0" @@ -1140,6 +1217,34 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f02d8aa6e3c385bf084924f660ce2a3a6bd333ba55b35e8590b321f35d88513" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap", + "serde", + "serde_json", + "serde_with_macros", + "time 0.3.22", +] + +[[package]] +name = "serde_with_macros" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc7d5d3932fb12ce722ee5e64dd38c504efba37567f0c402f6ca728c3b8b070" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.15", +] + [[package]] name = "sha2" version = "0.9.9" @@ -1186,6 +1291,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "subtle" version = "2.4.1" @@ -1245,6 +1356,33 @@ dependencies = [ "winapi", ] +[[package]] +name = "time" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +dependencies = [ + "time-core", +] + [[package]] name = "toml" version = "0.5.11" From f9357904bed0448d771ba9a34da5bc2b45efbb88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Wed, 21 Jun 2023 11:15:01 +0200 Subject: [PATCH 23/41] Fix failing unit tests --- packages/nodejs/test/clientV2.test.ts | 1 + .../nodejs/test/getConsensusStatus.test.ts | 1 - .../nodejs/test/resources/expectedJsons.ts | 98 +++++++++++-------- 3 files changed, 56 insertions(+), 44 deletions(-) diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index aa1a15662..569fc7580 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -213,6 +213,7 @@ test.each([clientV2, clientWeb])( expect(status).toEqual(expected.passiveDelegationStatus); } ); + test.each([clientV2, clientWeb])( 'getPoolInfo corresponds to getPoolStatus with bakerId (with pending change)', async (client) => { diff --git a/packages/nodejs/test/getConsensusStatus.test.ts b/packages/nodejs/test/getConsensusStatus.test.ts index 8787b3133..241279cd0 100644 --- a/packages/nodejs/test/getConsensusStatus.test.ts +++ b/packages/nodejs/test/getConsensusStatus.test.ts @@ -54,7 +54,6 @@ test('retrieves the consensus status from the node with correct types', async () expect(Number.isNaN(consensusStatus.genesisIndex)).toBeFalsy(), expect(typeof consensusStatus.epochDuration === 'bigint').toBeTruthy(), - expect(typeof consensusStatus.slotDuration === 'bigint').toBeTruthy(), expect( typeof consensusStatus.bestBlockHeight === 'bigint' ).toBeTruthy(), diff --git a/packages/nodejs/test/resources/expectedJsons.ts b/packages/nodejs/test/resources/expectedJsons.ts index 2cee6a94c..4efdaf652 100644 --- a/packages/nodejs/test/resources/expectedJsons.ts +++ b/packages/nodejs/test/resources/expectedJsons.ts @@ -1,7 +1,12 @@ import { AccountAddress, + BlockInfoV0, CcdAmount, + ChainParametersV0, + ChainParametersV1, + ElectionInfoV0, ModuleReference, + NextUpdateSequenceNumbers, } from '@concordium/common-sdk'; export const accountInfo = { @@ -383,7 +388,7 @@ export const passiveDelegatorRewardInfoList = [ }, ]; -export const electionInfoList = { +export const electionInfoList: ElectionInfoV0 = { electionDifficulty: 0.025, electionNonce: '0bb2121015ddd9026d0c31a8b33499ce6049daf5696fe4e2cd94cff83ad331f2', @@ -462,7 +467,7 @@ export const transactionEventList = [ }, }, ]; -export const seqNums = { +export const seqNums: NextUpdateSequenceNumbers = { rootKeys: 1n, level1Keys: 1n, level2Keys: 1n, @@ -479,6 +484,10 @@ export const seqNums = { addIdentityProvider: 1n, cooldownParameters: 1n, timeParameters: 1n, + timeoutParameters: 1n, + blockEnergyLimit: 1n, + minBlockTime: 1n, + finalizationCommiteeParameters: 1n, }; export const specialEventList = [ @@ -1601,7 +1610,7 @@ export const regularAccountInfo = { accountAddress: '3kBx2h5Y2veb4hZgAJWPrr8RyQESKm5TjzF3ti1QQ4VSYLwK1G', }; -export const chainParameters = { +export const chainParameters: ChainParametersV1 = { electionDifficulty: 0.025, euroPerEnergy: { numerator: 1n, denominator: 50000n }, microGTUPerEuro: { @@ -1610,32 +1619,36 @@ export const chainParameters = { }, accountCreationLimit: 10, foundationAccount: '3kBx2h5Y2veb4hZgAJWPrr8RyQESKm5TjzF3ti1QQ4VSYLwK1G', - rewardPeriodLength: 24n, - mintPerPayday: 0.000261157877, - delegatorCooldown: 1209600n, - poolOwnerCooldown: 1814400n, - passiveFinalizationCommission: 1, - passiveBakingCommission: 0.12, - passiveTransactionCommission: 0.12, - finalizationCommissionRange: { min: 1, max: 1 }, - bakingCommissionRange: { min: 0.1, max: 0.1 }, - transactionCommissionRange: { min: 0.1, max: 0.1 }, - minimumEquityCapital: 14000000000n, - capitalBound: 0.1, - leverageBound: { numerator: 3n, denominator: 1n }, - rewardParameters: { - transactionFeeDistribution: { baker: 0.45, gasAccount: 0.45 }, - gASRewards: { - baker: 0.25, - finalizationProof: 0.005, - accountCreation: 0.02, - chainUpdate: 0.005, - }, - mintDistribution: { bakingReward: 0.6, finalizationReward: 0.3 }, - }, -}; - -export const oldChainParameters = { + timeParameters: { + mintPerPayday: 0.000261157877, + rewardPeriodLength: 24n, + }, + cooldownParameters: { + delegatorCooldown: 1209600n, + poolOwnerCooldown: 1814400n, + }, + poolParameters: { + passiveFinalizationCommission: 1, + passiveBakingCommission: 0.12, + passiveTransactionCommission: 0.12, + finalizationCommissionRange: { min: 1, max: 1 }, + bakingCommissionRange: { min: 0.1, max: 0.1 }, + transactionCommissionRange: { min: 0.1, max: 0.1 }, + minimumEquityCapital: 14000000000n, + capitalBound: 0.1, + leverageBound: { numerator: 3n, denominator: 1n }, + }, + transactionFeeDistribution: { baker: 0.45, gasAccount: 0.45 }, + gasRewards: { + baker: 0.25, + finalizationProof: 0.005, + accountCreation: 0.02, + chainUpdate: 0.005, + }, + mintDistribution: { bakingReward: 0.6, finalizationReward: 0.3 }, +}; + +export const oldChainParameters: ChainParametersV0 = { electionDifficulty: 0.025, euroPerEnergy: { numerator: 1n, denominator: 50000n }, microGTUPerEuro: { numerator: 50000000n, denominator: 1n }, @@ -1643,19 +1656,17 @@ export const oldChainParameters = { foundationAccount: '3kBx2h5Y2veb4hZgAJWPrr8RyQESKm5TjzF3ti1QQ4VSYLwK1G', bakerCooldownEpochs: 166n, minimumThresholdForBaking: 15000000000n, - rewardParameters: { - transactionFeeDistribution: { baker: 0.45, gasAccount: 0.45 }, - gASRewards: { - baker: 0.25, - finalizationProof: 0.005, - accountCreation: 0.02, - chainUpdate: 0.005, - }, - mintDistribution: { - bakingReward: 0.6, - finalizationReward: 0.3, - mintPerSlot: 7.555665e-10, - }, + transactionFeeDistribution: { baker: 0.45, gasAccount: 0.45 }, + gasRewards: { + baker: 0.25, + finalizationProof: 0.005, + accountCreation: 0.02, + chainUpdate: 0.005, + }, + mintDistribution: { + bakingReward: 0.6, + finalizationReward: 0.3, + mintPerSlot: 7.555665e-10, }, }; @@ -1750,7 +1761,7 @@ export const blocksAtHeight = [ '99ceb0dfcd36714d9c141fde08e85da1d0d624994e95b35114f14193c811b76e', ]; -export const blockInfo = { +export const blockInfo: BlockInfoV0 = { blockParent: '28d92ec42dbda119f0b0207d3400b0573fe8baf4b0d3dbe44b86781ad6b655cf', blockHash: @@ -1771,6 +1782,7 @@ export const blockInfo = { transactionEnergyCost: 0n, genesisIndex: 1, eraBlockHeight: 1258806, + protocolVersion: 3n, }; export const bakers = [ From de94c544cc7d625f6687ce765b3891fccd2cb168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Wed, 21 Jun 2023 11:32:08 +0200 Subject: [PATCH 24/41] Fix examples --- examples/client/getBlockChainParameters.ts | 13 +++++++++---- examples/client/getElectionInfo.ts | 11 +++++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/examples/client/getBlockChainParameters.ts b/examples/client/getBlockChainParameters.ts index 8038fdac5..790b80a2a 100644 --- a/examples/client/getBlockChainParameters.ts +++ b/examples/client/getBlockChainParameters.ts @@ -3,6 +3,7 @@ import { ChainParameters, createConcordiumClient, isChainParametersV1, + isChainParametersV2, } from '@concordium/node-sdk'; import { credentials } from '@grpc/grpc-js'; @@ -53,13 +54,17 @@ const client = createConcordiumClient( const euroPerEnergy = cp.euroPerEnergy.numerator + '/' + cp.euroPerEnergy.denominator; - console.log('Election difficulty:', cp.electionDifficulty); console.log('Account creation limit:', cp.accountCreationLimit); console.log('Euro per Energy:', euroPerEnergy); - // Check if the ChainParameters is V1, which it will be for all newer blocks - if (isChainParametersV1(cp)) { - console.log('Minimum equity capital:', cp.minimumEquityCapital); + // Check version of chain parameters + if (isChainParametersV2(cp)) { + console.log('Minimum block time', cp.consensusParameters.minBlockTime); + } else if (isChainParametersV1(cp)) { + console.log( + 'Minimum equity capital:', + cp.poolParameters.minimumEquityCapital + ); } else { console.log( 'Chain parameters is V0 and does not contain information on minimum equity capital' diff --git a/examples/client/getElectionInfo.ts b/examples/client/getElectionInfo.ts index d43909376..be2252082 100644 --- a/examples/client/getElectionInfo.ts +++ b/examples/client/getElectionInfo.ts @@ -1,5 +1,9 @@ import { parseEndpoint } from '../shared/util'; -import { createConcordiumClient, ElectionInfo } from '@concordium/node-sdk'; +import { + createConcordiumClient, + ElectionInfo, + isElectionInfoV0, +} from '@concordium/node-sdk'; import { credentials } from '@grpc/grpc-js'; import meow from 'meow'; @@ -56,6 +60,9 @@ const client = createConcordiumClient( const sortedBakers = bakers.sort((xs, ys) => ys[1] - xs[1]); console.log('Bakers sorted by lottery power:', sortedBakers); - console.log('Election difficulty:', electionInfo.electionDifficulty); console.log('Election nonce:', electionInfo.electionNonce); + + if (isElectionInfoV0(electionInfo)) { + console.log('Election difficulty:', electionInfo.electionDifficulty); + } })(); From 5cdc5caa93d13bfb79efd94f3240f2ff8ff725ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Wed, 21 Jun 2023 11:57:57 +0200 Subject: [PATCH 25/41] More changelog --- packages/common/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 61c6ec46d..5a30ce0c2 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -7,6 +7,10 @@ - Bumped @concordium/rust-bindings to 1.0.0. (Throws proper `Error`s when execution fails for any WASM entrypoint, with improved error messages) - Updated `types.ts` to conform to updated GRPC API, which includes adding more variants to existing types (all new variants take effect from protocol version 6): - `ChainParametersV2` added to `ChainParameters` + - The following parameters on `ChainParametersV1` have been moved into objects to align with GRPC api: + - `passiveFinalizationCommission`, `passiveBakingCommission`, `passiveTransactionCommission`, `finalizationCommissionRange`, `bakingCommissionRange`, `transactionCommissionRange`, `minimumEquityCapital`, `capitalBound`, `leverageBound` have been moved to `poolParameters` + - `poolOwnerCooldown`, `delegatorCooldown` have been moved to `cooldownParameters` + - `rewardPeriodLength`, `mintPerPayday` have been moved to `timeParameters` - `BlockInfo` changed to `BlockInfoV0 | BlockInfoV1` - `ConsensusStatus` changed to `ConsensusStatusV0 | ConsensusStatusV1` - `ElectionInfo` changed to `ElectionInfoV0 | ElectionInfoV1` From d460c7121b54a65439c4ec1d72f338e01d22efa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Wed, 21 Jun 2023 12:10:35 +0200 Subject: [PATCH 26/41] PR feedback --- packages/common/src/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 935333293..d8450e16d 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -309,7 +309,7 @@ export interface RewardParametersV0 extends RewardParametersCommon { } /** - * Used from protocol version 4-5 + * Used in protocol versions 4 and 5 */ export interface RewardParametersV1 extends RewardParametersCommon { mintDistribution: MintDistributionV1; @@ -396,7 +396,7 @@ export type ChainParametersV0 = ChainParametersCommon & }; /** - * Used from protocol version 4-5 + * Used in protocol versions 4 and 5 */ export type ChainParametersV1 = ChainParametersCommon & RewardParametersV1 & { From b164426c968331887b98756f58bf8fff1911f408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Wed, 21 Jun 2023 12:33:27 +0200 Subject: [PATCH 27/41] Updated types to aliases --- packages/common/src/types.ts | 37 ++++++++++++++---------- packages/common/src/types/chainUpdate.ts | 3 +- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index d8450e16d..f00b555ef 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -32,10 +32,14 @@ export type JsonString = string; export type ModuleRef = HexString; -// A number of milliseconds +/** A number of milliseconds */ export type Duration = bigint; -// Unix timestamp in milliseconds +/** Unix timestamp in milliseconds */ export type Timestamp = bigint; +/** A consensus round */ +export type Round = bigint; +/** An amount of energy */ +export type Energy = bigint; /** * Returns a union of all keys of type T with values matching type V. @@ -369,7 +373,7 @@ export interface TimeoutParameters { export interface ConsensusParameters { timeoutParameters: TimeoutParameters; minBlockTime: Duration; - blockEnergyLimit: bigint; + blockEnergyLimit: Energy; } export interface FinalizationCommitteeParameters { @@ -382,7 +386,7 @@ export interface ChainParametersCommon { euroPerEnergy: ExchangeRate; microGTUPerEuro: ExchangeRate; accountCreationLimit: number; - foundationAccount: string; + foundationAccount: Base58String; } /** @@ -655,8 +659,8 @@ export interface BlockInfoV0 extends BlockInfoCommon { /** Used from protocol version 6 */ export interface BlockInfoV1 extends BlockInfoCommon { - round: bigint; - epoch: bigint; + round: Round; + epoch: Epoch; } export type BlockInfo = BlockInfoV0 | BlockInfoV1; @@ -681,15 +685,15 @@ export type BlocksAtHeightRequest = | RelativeBlocksAtHeightRequest; export interface ConsensusStatusCommon { - bestBlock: string; - genesisBlock: string; - currentEraGenesisBlock: string; - lastFinalizedBlock: string; + bestBlock: HexString; + genesisBlock: HexString; + currentEraGenesisBlock: HexString; + lastFinalizedBlock: HexString; /** * In milliseconds */ - epochDuration: bigint; + epochDuration: Duration; bestBlockHeight: bigint; lastFinalizedBlockHeight: bigint; @@ -733,13 +737,16 @@ export interface ConsensusStatusV0 extends ConsensusStatusCommon { /** * In milliseconds */ - slotDuration: bigint; + slotDuration: Duration; } export interface ConcordiumBFTStatus { - currentTimeoutDuration: bigint; - currentRound: bigint; - currentEpoch: bigint; + /** + * In milliseconds + */ + currentTimeoutDuration: Duration; + currentRound: Round; + currentEpoch: Epoch; triggerBlockTime: Date; } diff --git a/packages/common/src/types/chainUpdate.ts b/packages/common/src/types/chainUpdate.ts index d3ec8f0ff..fe173efe4 100644 --- a/packages/common/src/types/chainUpdate.ts +++ b/packages/common/src/types/chainUpdate.ts @@ -4,6 +4,7 @@ import { AuthorizationsV1, Base58String, Duration, + Energy, FinalizationCommitteeParameters, GasRewardsV0, GasRewardsV1, @@ -108,7 +109,7 @@ export interface MinBlockTimeUpdate { export interface BlockEnergyLimitUpdate { updateType: UpdateType.BlockEnergyLimit; - update: bigint; + update: Energy; } export interface FinalizationCommitteeParametersUpdate { From d3fdc573f2cfcdb6b5fadf081142bbfb1eb395dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Wed, 21 Jun 2023 15:48:10 +0200 Subject: [PATCH 28/41] Rename reference to GTU --- packages/common/CHANGELOG.md | 1 + packages/common/src/GRPCTypeTranslation.ts | 2 +- packages/common/src/energyCost.ts | 2 +- packages/common/src/types.ts | 136 ++++++++++++++---- .../nodejs/test/resources/expectedJsons.ts | 4 +- 5 files changed, 114 insertions(+), 31 deletions(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 5a30ce0c2..04ce130b3 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -7,6 +7,7 @@ - Bumped @concordium/rust-bindings to 1.0.0. (Throws proper `Error`s when execution fails for any WASM entrypoint, with improved error messages) - Updated `types.ts` to conform to updated GRPC API, which includes adding more variants to existing types (all new variants take effect from protocol version 6): - `ChainParametersV2` added to `ChainParameters` + - `ChainParameters` field `microGTUPerEuro` is now called `microCCDPerEuro`. - The following parameters on `ChainParametersV1` have been moved into objects to align with GRPC api: - `passiveFinalizationCommission`, `passiveBakingCommission`, `passiveTransactionCommission`, `finalizationCommissionRange`, `bakingCommissionRange`, `transactionCommissionRange`, `minimumEquityCapital`, `capitalBound`, `leverageBound` have been moved to `poolParameters` - `poolOwnerCooldown`, `delegatorCooldown` have been moved to `cooldownParameters` diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index 35a6e1f5a..455fea1a6 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -255,7 +255,7 @@ function translateChainParametersCommon( ): v1.ChainParametersCommon { return { euroPerEnergy: unwrap(params.euroPerEnergy?.value), - microGTUPerEuro: unwrap(params.microCcdPerEuro?.value), + microCCDPerEuro: unwrap(params.microCcdPerEuro?.value), accountCreationLimit: unwrap(params.accountCreationLimit?.value), foundationAccount: unwrapToBase58(params.foundationAccount), }; diff --git a/packages/common/src/energyCost.ts b/packages/common/src/energyCost.ts index 11b168678..b60357e8f 100644 --- a/packages/common/src/energyCost.ts +++ b/packages/common/src/energyCost.ts @@ -64,7 +64,7 @@ export function getEnergyCost( */ export function getExchangeRate({ euroPerEnergy, - microGTUPerEuro, + microCCDPerEuro: microGTUPerEuro, }: ChainParameters): Ratio { const denominator = BigInt( euroPerEnergy.denominator * microGTUPerEuro.denominator diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index f00b555ef..70a85fcf7 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -288,140 +288,212 @@ export type MintDistributionV1 = MintDistributionCommon; export type MintDistribution = MintDistributionV0 | MintDistributionV1; +/** Common gas rewards properties across all protocol versions */ export interface GasRewardsCommon { + /** The fractional amount paid to the baker */ baker: number; + /** The fractional amount paid for an account creation */ accountCreation: number; + /** The fractional amount paid for a chain update */ chainUpdate: number; } +/** Gas rewards properties for protocol version 1-5 ({@link ChainParametersV0} and {@link ChainParametersV1}). */ export interface GasRewardsV0 extends GasRewardsCommon { + /** The fractional amount paid for including a finalization proof */ finalizationProof: number; } +/** Gas rewards properties from protocol version 6 ({@link ChainParametersV2}). */ export type GasRewardsV1 = GasRewardsCommon; +/** Common reward parameters used across all protocol versions */ export interface RewardParametersCommon { + /** The current transaction fee distribution */ transactionFeeDistribution: TransactionFeeDistribution; } -/** - * Used from protocol version 1-3 - */ +/** Reward parameters used from protocol version 1-3 ({@link ChainParametersV0}). */ export interface RewardParametersV0 extends RewardParametersCommon { + /** The current mint distribution */ mintDistribution: MintDistributionV0; + /** The current gas rewards parameters */ gasRewards: GasRewardsV0; } -/** - * Used in protocol versions 4 and 5 - */ +/** Reward parameters used in protocol versions 4 and 5 ({@link ChainParametersV1}). */ export interface RewardParametersV1 extends RewardParametersCommon { + /** The current mint distribution */ mintDistribution: MintDistributionV1; + /** The current gas rewards parameters */ gasRewards: GasRewardsV0; } -/** - * Used from protocol version 6 - */ +/** Reward parameters used from protocol version 6 ({@link ChainParametersV2}). */ export interface RewardParametersV2 extends RewardParametersCommon { + /** The current mint distribution */ mintDistribution: MintDistributionV1; + /** The current gas rewards parameters */ gasRewards: GasRewardsV1; } +/** Cooldown parameters used from protocol version 1-3 */ export interface CooldownParametersV0 { + /** The baker cooldown period in {@link Epoch} epochs */ bakerCooldownEpochs: Epoch; } +/** Cooldown parameters used from protocol version 4 */ export interface CooldownParametersV1 { + /** The pool owner (baker) cooldown period in seconds */ poolOwnerCooldown: DurationSeconds; + /** The delegator cooldown period in seconds */ delegatorCooldown: DurationSeconds; } +/** Pool parameters used from protocol version 1-3 */ export interface PoolParametersV0 { + /** The minimum threshold to stake to become a baker. */ minimumThresholdForBaking: Amount; } +/** Pool parameters used from protocol version 4 */ export interface PoolParametersV1 { + /** Fraction of finalization rewards charged by the passive delegation. */ passiveFinalizationCommission: number; + /** Fraction of baking rewards charged by the passive delegation.*/ passiveBakingCommission: number; + /* Fraction of transaction rewards charged by the L-pool.*/ passiveTransactionCommission: number; + /** Fraction of finalization rewards charged by the pool owner. */ finalizationCommissionRange: InclusiveRange; + /** Fraction of baking rewards charged by the pool owner. */ bakingCommissionRange: InclusiveRange; + /** Fraction of transaction rewards charged by the pool owner. */ transactionCommissionRange: InclusiveRange; + /** Minimum equity capital required for a new baker.*/ minimumEquityCapital: Amount; + /** + * Maximum fraction of the total staked capital of that a new baker can + * have. + */ capitalBound: number; + /** + * The maximum leverage that a baker can have as a ratio of total stake + * to equity capital. + */ leverageBound: Ratio; } +/** + * Time parameters used from protocol version 4 + * These consist of the reward period length and the mint rate per payday. These are coupled as + * a change to either affects the overall rate of minting. + */ export interface TimeParametersV1 { - /** - * In epochs - */ + /** The length of a reward period, in {@link Epoch} epochs. */ rewardPeriodLength: Epoch; + /** The rate at which CCD is minted per payday. */ mintPerPayday: number; } +/** Parameters that determine timeouts in the consensus protocol used from protocol version 6. */ export interface TimeoutParameters { - /** - * In milliseconds. - */ + /** The base value for triggering a timeout, in milliseconds. */ timeoutBase: Duration; + /** Factor for increasing the timeout. Must be greater than 1. */ timeoutIncrease: Ratio; + /** Factor for decreasing the timeout. Must be between 0 and 1. */ timeoutDecrease: Ratio; } +/** Consensus parameters, used from protocol version 6 */ export interface ConsensusParameters { + /** Parameters controlling round timeouts. */ timeoutParameters: TimeoutParameters; + /** Minimum time interval between blocks. */ minBlockTime: Duration; + /** Maximum energy allowed per block. */ blockEnergyLimit: Energy; } +/** + * Finalization committee parameters, used from protocol version 6 + */ export interface FinalizationCommitteeParameters { + /** The minimum size of a finalization committee before `finalizer_relative_stake_threshold` takes effect. */ minimumFinalizers: number; + /** The maximum size of a finalization committee. */ maximumFinalizers: number; + /** + * The threshold for determining the stake required for being eligible the finalization committee. + * The amount is given by `total stake in pools * finalizer_relative_stake_threshold` + */ finalizerRelativeStakeThreshold: number; } +/** Common chain parameters across all protocol versions */ export interface ChainParametersCommon { + /** Rate of euros per energy */ euroPerEnergy: ExchangeRate; - microGTUPerEuro: ExchangeRate; + /** Rate of micro CCD per euro */ + microCCDPerEuro: ExchangeRate; + /** Limit for the number of account creations in a block */ accountCreationLimit: number; + /** The chain foundation account */ foundationAccount: Base58String; } -/** - * Used from protocol version 1-3 - */ +/** Chain parameters used from protocol version 1-3 */ export type ChainParametersV0 = ChainParametersCommon & CooldownParametersV0 & PoolParametersV0 & RewardParametersV0 & { + /** The election difficulty for consensus lottery */ electionDifficulty: number; }; -/** - * Used in protocol versions 4 and 5 - */ +/** Chain parameters used in protocol versions 4 and 5 */ export type ChainParametersV1 = ChainParametersCommon & RewardParametersV1 & { + /** + * The extra number of epochs before reduction in stake + * or baker deregistration is completed. + */ cooldownParameters: CooldownParametersV1; + /** + * The time parameters, indicating the mint rate and + * the reward period length, i.e. the tiem between paydays + */ timeParameters: TimeParametersV1; + /** Parameters governing baking pools and their commissions. */ poolParameters: PoolParametersV1; + /** The election difficulty for consensus lottery */ electionDifficulty: number; }; -/** - * Used from protocol version 6 - */ +/** Chain parameters used from protocol version 6 */ export type ChainParametersV2 = ChainParametersCommon & RewardParametersV2 & { + /** The consensus parameters. */ consensusParameters: ConsensusParameters; + /** + * The extra number of epochs before reduction in stake + * or baker deregistration is completed. + */ cooldownParameters: CooldownParametersV1; + /** + * The time parameters, indicating the mint rate and + * the reward period length, i.e. the tiem between paydays + */ timeParameters: TimeParametersV1; + /** Parameters governing baking pools and their commissions. */ poolParameters: PoolParametersV1; + /** The finalization committee parameters */ finalizationCommiteeParameters: FinalizationCommitteeParameters; }; +/** Union of all chain parameters across all protocol versions */ export type ChainParameters = | ChainParametersV0 | ChainParametersV1 @@ -628,6 +700,9 @@ export interface RewardStatusV1 extends RewardStatusCommon { export type RewardStatus = RewardStatusV0 | RewardStatusV1; export type TokenomicsInfo = RewardStatus; +/** + * Common properties for block info across all protocol versions + */ export interface BlockInfoCommon { blockParent: HexString; blockHash: HexString; @@ -652,17 +727,24 @@ export interface BlockInfoCommon { protocolVersion: bigint; } -/** Used for protocol version 1-5 */ +/** + * Block info used for protocol version 1-5 + */ export interface BlockInfoV0 extends BlockInfoCommon { blockSlot: bigint; } -/** Used from protocol version 6 */ +/** + * Block info used for protocol version 6 + */ export interface BlockInfoV1 extends BlockInfoCommon { round: Round; epoch: Epoch; } +/** + * Union of all block info versions + */ export type BlockInfo = BlockInfoV0 | BlockInfoV1; export interface CommonBlockInfo { diff --git a/packages/nodejs/test/resources/expectedJsons.ts b/packages/nodejs/test/resources/expectedJsons.ts index 4efdaf652..a42fdce4a 100644 --- a/packages/nodejs/test/resources/expectedJsons.ts +++ b/packages/nodejs/test/resources/expectedJsons.ts @@ -1613,7 +1613,7 @@ export const regularAccountInfo = { export const chainParameters: ChainParametersV1 = { electionDifficulty: 0.025, euroPerEnergy: { numerator: 1n, denominator: 50000n }, - microGTUPerEuro: { + microCCDPerEuro: { numerator: 697170112016908288n, denominator: 7989497115n, }, @@ -1651,7 +1651,7 @@ export const chainParameters: ChainParametersV1 = { export const oldChainParameters: ChainParametersV0 = { electionDifficulty: 0.025, euroPerEnergy: { numerator: 1n, denominator: 50000n }, - microGTUPerEuro: { numerator: 50000000n, denominator: 1n }, + microCCDPerEuro: { numerator: 50000000n, denominator: 1n }, accountCreationLimit: 10, foundationAccount: '3kBx2h5Y2veb4hZgAJWPrr8RyQESKm5TjzF3ti1QQ4VSYLwK1G', bakerCooldownEpochs: 166n, From 8ae6dbec878e4bc0cc4ce0d937796ca7620e90ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 22 Jun 2023 10:10:18 +0200 Subject: [PATCH 29/41] More doc comments to added/changed types + renamed GTU references --- packages/common/CHANGELOG.md | 2 + packages/common/src/GRPCTypeTranslation.ts | 6 +-- packages/common/src/energyCost.ts | 6 +-- packages/common/src/types.ts | 49 +++++++++++++------ packages/common/src/types/chainUpdate.ts | 8 +-- .../nodejs/test/resources/expectedJsons.ts | 4 +- 6 files changed, 47 insertions(+), 28 deletions(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 04ce130b3..97b1315b9 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -15,6 +15,8 @@ - `BlockInfo` changed to `BlockInfoV0 | BlockInfoV1` - `ConsensusStatus` changed to `ConsensusStatusV0 | ConsensusStatusV1` - `ElectionInfo` changed to `ElectionInfoV0 | ElectionInfoV1` +- Renamed type `MicroGtuPerEuroUpdate` to `MicroCCDPerEuroUpdate` +- Renamed enum member `UpdateType.MicroGtuPerEuro` to `UpdateType.MicroCCDPerEuro`, along with it's corresponding string value from `"microGtuPerEuro"` to `"microCCDPerEuro"`. ### Fixed diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index 455fea1a6..7308c1dce 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -1272,9 +1272,9 @@ function trEuroPerEnergyUpdate( } function trMicroCcdPerEuroUpdate( exchangeRate: v2.ExchangeRate -): v1.MicroGtuPerEuroUpdate { +): v1.MicroCCDPerEuroUpdate { return { - updateType: v1.UpdateType.MicroGtuPerEuro, + updateType: v1.UpdateType.MicroCCDPerEuro, update: unwrap(exchangeRate.value), }; } @@ -1737,7 +1737,7 @@ function trAuthorizationsV0(auths: v2.AuthorizationsV0): v1.AuthorizationsV0 { consensus: trAccessStructure(auths.parameterConsensus), euroPerEnergy: trAccessStructure(auths.parameterEuroPerEnergy), foundationAccount: trAccessStructure(auths.parameterFoundationAccount), - microGTUPerEuro: trAccessStructure(auths.parameterMicroCCDPerEuro), + microCCDPerEuro: trAccessStructure(auths.parameterMicroCCDPerEuro), paramGASRewards: trAccessStructure(auths.parameterGasRewards), mintDistribution: trAccessStructure(auths.parameterMintDistribution), transactionFeeDistribution: trAccessStructure( diff --git a/packages/common/src/energyCost.ts b/packages/common/src/energyCost.ts index b60357e8f..4735c16d6 100644 --- a/packages/common/src/energyCost.ts +++ b/packages/common/src/energyCost.ts @@ -64,13 +64,13 @@ export function getEnergyCost( */ export function getExchangeRate({ euroPerEnergy, - microCCDPerEuro: microGTUPerEuro, + microCCDPerEuro, }: ChainParameters): Ratio { const denominator = BigInt( - euroPerEnergy.denominator * microGTUPerEuro.denominator + euroPerEnergy.denominator * microCCDPerEuro.denominator ); const numerator = BigInt( - euroPerEnergy.numerator * microGTUPerEuro.numerator + euroPerEnergy.numerator * microCCDPerEuro.numerator ); return { numerator, denominator }; } diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 70a85fcf7..a02a0f69a 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -506,7 +506,7 @@ export interface Authorization { interface AuthorizationsCommon { emergency: Authorization; - microGTUPerEuro: Authorization; + microCCDPerEuro: Authorization; euroPerEnergy: Authorization; transactionFeeDistribution: Authorization; foundationAccount: Authorization; @@ -578,7 +578,7 @@ export interface UpdateQueue { } interface UpdateQueuesCommon { - microGTUPerEuro: UpdateQueue; + microCCDPerEuro: UpdateQueue; euroPerEnergy: UpdateQueue; transactionFeeDistribution: UpdateQueue; foundationAccount: UpdateQueue; @@ -700,51 +700,68 @@ export interface RewardStatusV1 extends RewardStatusCommon { export type RewardStatus = RewardStatusV0 | RewardStatusV1; export type TokenomicsInfo = RewardStatus; -/** - * Common properties for block info across all protocol versions - */ +/** Common properties for block info across all protocol versions */ export interface BlockInfoCommon { + /** + * Hash of parent block. For the initial genesis block (i.e. not re-genesis) + * this will be the hash of the block itself + */ blockParent: HexString; + /** Hash of block */ blockHash: HexString; + /** Hash of block state */ blockStateHash: HexString; + /** Hash of last finalized block when this block was baked */ blockLastFinalized: HexString; + /** The absolute height of this (i.e. relative to the initial genesis block) */ blockHeight: bigint; + /** The baker ID of the baker for this block. Not available for a genesis block */ blockBaker?: BakerId; + /** The time the block was verified */ blockArriveTime: Date; + /** The time the block was received */ blockReceiveTime: Date; + /** The time of the slot in which the block was baked */ blockSlotTime: Date; + /** Whether the block is finalized */ finalized: boolean; + /** The number of transactions in the block */ transactionCount: bigint; + /** The total byte size of all transactions in the block */ transactionsSize: bigint; - transactionEnergyCost: bigint; + /** The energy cost of the transactions in the block */ + transactionEnergyCost: Energy; + /** + * The genesis index for the block. This counst the number of protocol updates that have + * preceeded this block, and defines the era of the block. + */ genesisIndex: number; + /** The height of this block relative to the (re)genesis block of its era */ eraBlockHeight: number; + /** The protocol version the block belongs to */ protocolVersion: bigint; } -/** - * Block info used for protocol version 1-5 - */ +/** Block info used for protocol version 1-5 */ export interface BlockInfoV0 extends BlockInfoCommon { + /** The slot number in which the block was baked. */ blockSlot: bigint; } -/** - * Block info used for protocol version 6 - */ +/** Block info used from protocol version 6 */ export interface BlockInfoV1 extends BlockInfoCommon { + /** The block round */ round: Round; + /** The block epoch */ epoch: Epoch; } -/** - * Union of all block info versions - */ +/** Union of all block info versions */ export type BlockInfo = BlockInfoV0 | BlockInfoV1; export interface CommonBlockInfo { @@ -1621,7 +1638,7 @@ export enum ParameterType { I32, /** Signed 64-bit integer. */ I64, - /** Token amount in microCCD (10^-6 GTU). */ + /** Token amount in microCCD (10^-6 CCD). */ Amount, /** Sender account address. */ AccountAddress, diff --git a/packages/common/src/types/chainUpdate.ts b/packages/common/src/types/chainUpdate.ts index fe173efe4..e0d1bcb55 100644 --- a/packages/common/src/types/chainUpdate.ts +++ b/packages/common/src/types/chainUpdate.ts @@ -42,8 +42,8 @@ export interface EuroPerEnergyUpdate { update: ExchangeRate; } -export interface MicroGtuPerEuroUpdate { - updateType: UpdateType.MicroGtuPerEuro; +export interface MicroCCDPerEuroUpdate { + updateType: UpdateType.MicroCCDPerEuro; update: ExchangeRate; } @@ -138,7 +138,7 @@ export interface PendingAuthorizationKeysUpdate { } export type CommonUpdate = - | MicroGtuPerEuroUpdate + | MicroCCDPerEuroUpdate | EuroPerEnergyUpdate | TransactionFeeDistributionUpdate | FoundationAccountUpdate @@ -173,7 +173,7 @@ export enum UpdateType { Protocol = 'protocol', ElectionDifficulty = 'electionDifficulty', EuroPerEnergy = 'euroPerEnergy', - MicroGtuPerEuro = 'microGtuPerEuro', + MicroCCDPerEuro = 'microCCDPerEuro', FoundationAccount = 'foundationAccount', MintDistribution = 'mintDistribution', TransactionFeeDistribution = 'transactionFeeDistribution', diff --git a/packages/nodejs/test/resources/expectedJsons.ts b/packages/nodejs/test/resources/expectedJsons.ts index a42fdce4a..fe8ab2b86 100644 --- a/packages/nodejs/test/resources/expectedJsons.ts +++ b/packages/nodejs/test/resources/expectedJsons.ts @@ -149,7 +149,7 @@ export const blockItemStatusUpdate = { type: 'updateTransaction', effectiveTime: 0n, payload: { - updateType: 'microGtuPerEuro', + updateType: 'microCCDPerEuro', update: { numerator: 17592435270983729152n, denominator: 163844642115n, @@ -459,7 +459,7 @@ export const transactionEventList = [ hash: '49d7b5c3234dc17bd904af0b63712dc0a6680b96ad556c5ac1103d8cdd128891', effectiveTime: 0n, payload: { - updateType: 'microGtuPerEuro', + updateType: 'microCCDPerEuro', update: { denominator: 126230907181n, numerator: 9397474320418127872n, From e144f37740e220e50a7123318796224873a68d42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 22 Jun 2023 10:25:02 +0200 Subject: [PATCH 30/41] Fixed c/p doc comment mistake --- packages/common/src/types.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index a02a0f69a..272f66f52 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -421,13 +421,14 @@ export interface ConsensusParameters { * Finalization committee parameters, used from protocol version 6 */ export interface FinalizationCommitteeParameters { - /** The minimum size of a finalization committee before `finalizer_relative_stake_threshold` takes effect. */ + /** The minimum size of a finalization committee before `finalizerRelativeStakeThreshold` takes effect. */ minimumFinalizers: number; /** The maximum size of a finalization committee. */ maximumFinalizers: number; /** * The threshold for determining the stake required for being eligible the finalization committee. - * The amount is given by `total stake in pools * finalizer_relative_stake_threshold` + * The amount is given by `total stake in pools * finalizerRelativeStakeThreshold`. + * Subsequently, this will alwas be a number between 0 and 1. */ finalizerRelativeStakeThreshold: number; } From 1233d75c79a96cf1f80afd76bf278d50c1c172bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 22 Jun 2023 11:33:02 +0200 Subject: [PATCH 31/41] More documentation --- packages/common/src/accountHelpers.ts | 4 ++ packages/common/src/contractHelpers.ts | 3 + packages/common/src/types.ts | 67 +++++++++++++++------ packages/common/src/versionedTypeHelpers.ts | 22 +++++-- 4 files changed, 73 insertions(+), 23 deletions(-) diff --git a/packages/common/src/accountHelpers.ts b/packages/common/src/accountHelpers.ts index cd311c1b5..6ca4f3461 100644 --- a/packages/common/src/accountHelpers.ts +++ b/packages/common/src/accountHelpers.ts @@ -9,19 +9,23 @@ import { GenerateBakerKeysOutput, } from './types'; +/** Whether {@link AccountInfo} parameter given is of type {@link AccountInfoDelegator}, i.e. the account is a delegator */ export const isDelegatorAccount = ( ai: AccountInfo ): ai is AccountInfoDelegator => (ai as AccountInfoDelegator).accountDelegation !== undefined; +/** Whether {@link AccountInfo} parameter given is of type {@link AccountInfoBaker}, i.e. the account is a baker. */ export const isBakerAccount = (ai: AccountInfo): ai is AccountInfoBaker => (ai as AccountInfoBaker).accountBaker !== undefined; +/** Whether the pending change given is of type {@link ReduceStakePendingChange} */ export const isReduceStakePendingChange = ( spc: ReduceStakePendingChange | RemovalPendingChange ): spc is ReduceStakePendingChange => (spc as ReduceStakePendingChange).newStake !== undefined; +/** Whether the pending change given is of type {@link RemovalPendingChange} */ export const isRemovalPendingChange = ( spc: ReduceStakePendingChange | RemovalPendingChange ): spc is RemovalPendingChange => !isReduceStakePendingChange(spc); diff --git a/packages/common/src/contractHelpers.ts b/packages/common/src/contractHelpers.ts index 1070221c3..46ab71d90 100644 --- a/packages/common/src/contractHelpers.ts +++ b/packages/common/src/contractHelpers.ts @@ -33,6 +33,9 @@ export const checkParameterLength = (buffer: Buffer): void => { } }; +/** + * Whether two {@link ContractAddress} contract addresses are equal. + */ export const isEqualContractAddress = (a: ContractAddress) => (b: ContractAddress): boolean => diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 272f66f52..1c51437fe 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -784,77 +784,106 @@ export type BlocksAtHeightRequest = | AbsoluteBlocksAtHeightRequest | RelativeBlocksAtHeightRequest; +/** Common properties for consensus status types used across all protocol versions */ export interface ConsensusStatusCommon { + /** Hash of the current best block */ bestBlock: HexString; + /** Hash of the initial genesis block */ genesisBlock: HexString; + /** Hash of the genesis block of the current era, i.e. since the last protocol update. */ currentEraGenesisBlock: HexString; + /** Hash of the last finalized block */ lastFinalizedBlock: HexString; - /** - * In milliseconds - */ + /** Current epoch duration, in milliseconds */ epochDuration: Duration; + /** Absolute height of the best block */ bestBlockHeight: bigint; + /** Absolute height of the last finalized block */ lastFinalizedBlockHeight: bigint; + /** Number of finalizations */ finalizationCount: bigint; + /** Total number of blocks received and verified */ blocksVerifiedCount: bigint; + /** Total number of blocks received */ blocksReceivedCount: bigint; + /** Exponential moving average latency between a block's slot time and its arrival. */ blockArriveLatencyEMA: number; + /** Standard deviation of exponential moving average latency between a block's slot time and its arrival. */ blockArriveLatencyEMSD: number; + /** Exponential moving average latency between a block's slot time and received time. */ blockReceiveLatencyEMA: number; + /** Standard deviation of exponential moving average latency between a block's slot time and received time. */ blockReceiveLatencyEMSD: number; + /** Exponential moving average number of transactions per block. */ transactionsPerBlockEMA: number; + /** Standard deviation of exponential moving average number of transactions per block. */ transactionsPerBlockEMSD: number; + /** Exponential moving average time between receiving blocks. */ blockReceivePeriodEMA?: number; + /** Standard deviation of exponential moving average time between receiving blocks. */ blockReceivePeriodEMSD?: number; + /** Exponential moving average time between block arrivals. */ blockArrivePeriodEMA?: number; + /** Standard deviation of exponential moving average time between block arrivals. */ blockArrivePeriodEMSD?: number; + /** Exponential moving average time between finalizations. */ finalizationPeriodEMA?: number; + /** Standard deviation of exponential moving average time between finalizations. */ finalizationPeriodEMSD?: number; + /** Time of the (original) genesis block. */ genesisTime: Date; + /** Time when the current era started. */ currentEraGenesisTime: Date; + /** The last time a block was received. */ blockLastReceivedTime?: Date; + /** The last time a block was verified (added to the tree). */ blockLastArrivedTime?: Date; + /** Time of last verified finalization. */ lastFinalizedTime?: Date; + /** + * The number of chain restarts via a protocol update. A completed + * protocol update instruction might not change the protocol version + * specified in the previous field, but it always increments the genesis + * index. + */ genesisIndex: number; + /** Currently active protocol version. */ protocolVersion: bigint; } -/** - * Used for protocol version 1-5 - */ +/** Consensus status used for protocol version 1-5 */ export interface ConsensusStatusV0 extends ConsensusStatusCommon { - /** - * In milliseconds - */ + /** (Current) slot duration in milliseconds */ slotDuration: Duration; } -export interface ConcordiumBFTStatus { - /** - * In milliseconds - */ +/** Consensus status used from protocol version 6 */ +export type ConsensusStatusV1 = ConsensusStatusCommon & { + /** Current duration before a round times out, in milliseconds */ currentTimeoutDuration: Duration; + /** Current round */ currentRound: Round; + /** Current epoch */ currentEpoch: Epoch; + /** + * The first block in the epoch with timestamp at least this is considered to be + * the trigger block for the epoch transition. + */ triggerBlockTime: Date; -} - -/** - * Used from protocol version 6 - */ -export type ConsensusStatusV1 = ConsensusStatusCommon & ConcordiumBFTStatus; +}; +/** Union of consensus status types used across all protocol versions */ export type ConsensusStatus = ConsensusStatusV0 | ConsensusStatusV1; export interface CryptographicParameters { diff --git a/packages/common/src/versionedTypeHelpers.ts b/packages/common/src/versionedTypeHelpers.ts index f38d5a00b..257c7c796 100644 --- a/packages/common/src/versionedTypeHelpers.ts +++ b/packages/common/src/versionedTypeHelpers.ts @@ -28,77 +28,91 @@ import { UpdateQueuesV1, } from './types'; +/** Whether {@link AccountInfo} parameter given is of type {@link AccountInfoBakerV0} */ export const isBakerAccountV0 = (ai: AccountInfo): ai is AccountInfoBakerV0 => (ai as AccountInfoBakerV1).accountBaker?.bakerPoolInfo === undefined; +/** Whether {@link AccountInfo} parameter given is of type {@link AccountInfoBakerV1} */ export const isBakerAccountV1 = (ai: AccountInfo): ai is AccountInfoBakerV1 => (ai as AccountInfoBakerV1).accountBaker?.bakerPoolInfo !== undefined; +/** Whether {@link StakePendingChange} parameter given is of type {@link StakePendingChangeV0} */ export const isStakePendingChangeV0 = ( spc: StakePendingChange ): spc is StakePendingChangeV0 => (spc as StakePendingChangeV0).epoch !== undefined; +/** Whether {@link StakePendingChange} parameter given is of type {@link StakePendingChangeV1} */ export const isStakePendingChangeV1 = ( spc: StakePendingChange ): spc is StakePendingChangeV1 => (spc as StakePendingChangeV1).effectiveTime !== undefined; -export const isAuthorizationsV0 = ( - as: Authorizations -): as is AuthorizationsV1 => !isAuthorizationsV1(as); - +/** Whether {@link Authorizations} parameter given is of type {@link AuthorizationsV1} */ export const isAuthorizationsV1 = ( as: Authorizations ): as is AuthorizationsV1 => (as as AuthorizationsV1).timeParameters !== undefined; +/** Whether {@link ChainParameters} parameter given is of type {@link ChainParametersV0} */ export const isChainParametersV0 = ( cp: ChainParameters ): cp is ChainParametersV0 => (cp as ChainParametersV0).minimumThresholdForBaking !== undefined; +/** Whether {@link ChainParameters} parameter given is of type {@link ChainParametersV1} */ export const isChainParametersV1 = ( cp: ChainParameters ): cp is ChainParametersV1 => (cp as ChainParametersV1).timeParameters !== undefined && !isChainParametersV2(cp); +/** Whether {@link ChainParameters} parameter given is of type {@link ChainParametersV2} */ export const isChainParametersV2 = ( cp: ChainParameters ): cp is ChainParametersV2 => (cp as ChainParametersV2).consensusParameters !== undefined; +/** Whether {@link Keys} parameter given is of type {@link KeysV0} */ export const isKeysV0 = (ks: Keys): ks is KeysV0 => !isAuthorizationsV1(ks.level2Keys); +/** Whether {@link Keys} parameter given is of type {@link KeysV1} */ export const isKeysV1 = (ks: Keys): ks is KeysV1 => isAuthorizationsV1(ks.level2Keys); +/** Whether {@link UpdateQueues} parameter given is of type {@link UpdateQueuesV0} */ export const isUpdateQueuesV0 = (uq: UpdateQueues): uq is UpdateQueuesV0 => (uq as UpdateQueuesV0).bakerStakeThreshold !== undefined; +/** Whether {@link UpdateQueues} parameter given is of type {@link UpdateQueuesV1} */ export const isUpdateQueuesV1 = (uq: UpdateQueues): uq is UpdateQueuesV1 => (uq as UpdateQueuesV1).timeParameters !== undefined; +/** Whether {@link BlockInfo} parameter given is of type {@link BlockInfoV0} */ export const isBlockInfoV0 = (bi: BlockInfo): bi is BlockInfoV0 => (bi as BlockInfoV0).blockSlot !== undefined; +/** Whether {@link BlockInfo} parameter given is of type {@link BlockInfoV1} */ export const isBlockInfoV1 = (bi: BlockInfo): bi is BlockInfoV1 => (bi as BlockInfoV1).round !== undefined; +/** Whether {@link ConensusStatus} parameter given is of type {@link ConsensusStatusV0} */ export const isConsensusStatusV0 = ( cs: ConsensusStatus ): cs is ConsensusStatusV0 => (cs as ConsensusStatusV0).slotDuration !== undefined; +/** Whether {@link ConensusStatus} parameter given is of type {@link ConsensusStatusV1} */ export const isConsensusStatusV1 = ( cs: ConsensusStatus ): cs is ConsensusStatusV1 => (cs as ConsensusStatusV1).currentRound !== undefined; +/** Whether {@link ElectionInfo} parameter given is of type {@link ElectionInfoV0} */ export const isElectionInfoV0 = (ei: ElectionInfo): ei is ElectionInfoV0 => (ei as ElectionInfoV0).electionDifficulty !== undefined; +/** Whether {@link ElectionInfo} parameter given is of type {@link ElectionInfoV1} */ export const isElectionInfoV1 = (ei: ElectionInfo): ei is ElectionInfoV1 => !isElectionInfoV0(ei); From e92e1ee0ed8dbd5d6e9f03596d6011ce1337463b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 22 Jun 2023 12:05:18 +0200 Subject: [PATCH 32/41] More doc comments --- packages/common/src/types.ts | 7 + packages/common/src/types/chainUpdate.ts | 255 +++++++++++++---------- 2 files changed, 147 insertions(+), 115 deletions(-) diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 1c51437fe..55f327fe4 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -1371,17 +1371,24 @@ export interface BakerElectionInfo { lotteryPower: number; } +/** Common properties for election info across all protocol versions */ export interface ElectionInfoCommon { electionNonce: HexString; bakerElectionInfo: BakerElectionInfo[]; } +/** Election info used for protocol version 1-5 */ export interface ElectionInfoV0 extends ElectionInfoCommon { electionDifficulty: number; } +/** Election info used from protocol version 6 */ export type ElectionInfoV1 = ElectionInfoCommon; +/** + * Union of different versions of election info across all protocol versions. + * Contains information related to baker election for a particular block + */ export type ElectionInfo = ElectionInfoV0 | ElectionInfoV1; export interface NextUpdateSequenceNumbers { diff --git a/packages/common/src/types/chainUpdate.ts b/packages/common/src/types/chainUpdate.ts index e0d1bcb55..61a1bd05e 100644 --- a/packages/common/src/types/chainUpdate.ts +++ b/packages/common/src/types/chainUpdate.ts @@ -22,121 +22,143 @@ import type { CommissionRates, } from '../types'; -export interface MintDistributionUpdate { - updateType: UpdateType.MintDistribution; - update: MintDistribution; -} - -export interface FoundationAccountUpdate { - updateType: UpdateType.FoundationAccount; - update: FoundationAccount; -} - -export interface ElectionDifficultyUpdate { - updateType: UpdateType.ElectionDifficulty; - update: ElectionDifficulty; -} - -export interface EuroPerEnergyUpdate { - updateType: UpdateType.EuroPerEnergy; - update: ExchangeRate; -} - -export interface MicroCCDPerEuroUpdate { - updateType: UpdateType.MicroCCDPerEuro; - update: ExchangeRate; -} - -export interface TransactionFeeDistributionUpdate { - updateType: UpdateType.TransactionFeeDistribution; - update: TransactionFeeDistribution; -} - -export interface GasRewardsV0Update { - updateType: UpdateType.GasRewards; - update: GasRewardsV0; -} - -export interface GasRewardsV1Update { - updateType: UpdateType.GasRewardsCpv2; - update: GasRewardsV1; -} - -export interface AddAnonymityRevokerUpdate { - updateType: UpdateType.AddAnonymityRevoker; - update: AddAnonymityRevoker; -} - -export interface AddIdentityProviderUpdate { - updateType: UpdateType.AddIdentityProvider; - update: AddIdentityProvider; -} - -export interface CooldownParametersUpdate { - updateType: UpdateType.CooldownParameters; - update: CooldownParameters; -} - -export interface TimeParametersUpdate { - updateType: UpdateType.TimeParameters; - update: TimeParameters; -} - -export interface ProtocolUpdate { - updateType: UpdateType.Protocol; - update: ProtocolUpdateDetails; -} - -export interface PoolParametersUpdate { - updateType: UpdateType.PoolParameters; - update: PoolParameters; -} - -export interface BakerStakeThresholdUpdate { - updateType: UpdateType.BakerStakeThreshold; - update: BakerStakeThreshold; -} - -export interface TimeoutParametersUpdate { - updateType: UpdateType.TimeoutParameters; - update: TimeoutParameters; -} - -export interface MinBlockTimeUpdate { - updateType: UpdateType.MinBlockTime; - update: Duration; -} - -export interface BlockEnergyLimitUpdate { - updateType: UpdateType.BlockEnergyLimit; - update: Energy; -} - -export interface FinalizationCommitteeParametersUpdate { - updateType: UpdateType.FinalizationCommitteeParameters; - update: FinalizationCommitteeParameters; -} - -export interface Level1Update { - updateType: UpdateType.Level1; - update: KeyUpdate; -} - -export interface RootUpdate { - updateType: UpdateType.Root; - update: KeyUpdate; -} - -export interface PendingHigherLevelKeyUpdate { - updateType: UpdateType.HigherLevelKeyUpdate; - update: HigherLevelKeyUpdate; -} - -export interface PendingAuthorizationKeysUpdate { - updateType: UpdateType.AuthorizationKeysUpdate; - update: AuthorizationKeysUpdate; -} - +type ChainUpdate = { + /** The type of the update */ + updateType: UpdateType; + /** The parameters used for the update */ + update: T; +}; + +/** An update to mint distribution parameters */ +export type MintDistributionUpdate = ChainUpdate< + UpdateType.MintDistribution, + MintDistribution +>; + +/** An update to the foundation account */ +export type FoundationAccountUpdate = ChainUpdate< + UpdateType.FoundationAccount, + FoundationAccount +>; + +/** An update to election difficulty parameters */ +export type ElectionDifficultyUpdate = ChainUpdate< + UpdateType.ElectionDifficulty, + ElectionDifficulty +>; + +/** An update to the euro per energy exchange rate */ +export type EuroPerEnergyUpdate = ChainUpdate< + UpdateType.EuroPerEnergy, + ExchangeRate +>; + +/** An update to the micro CCD per euro exchange rate */ +export type MicroCCDPerEuroUpdate = ChainUpdate< + UpdateType.MicroCCDPerEuro, + ExchangeRate +>; + +/** An update to transaction fee distribution parameters */ +export type TransactionFeeDistributionUpdate = ChainUpdate< + UpdateType.TransactionFeeDistribution, + TransactionFeeDistribution +>; + +/** An update to gas reward parameters for protocol version 1-5 */ +export type GasRewardsV0Update = ChainUpdate< + UpdateType.GasRewards, + GasRewardsV0 +>; + +/** An update to gas reward parameters from protocol version 6 */ +export type GasRewardsV1Update = ChainUpdate< + UpdateType.GasRewardsCpv2, + GasRewardsV1 +>; + +/** An update to add an anonymity revoker */ +export type AddAnonymityRevokerUpdate = ChainUpdate< + UpdateType.AddAnonymityRevoker, + AddAnonymityRevoker +>; + +/** An update to add an identity provider */ +export type AddIdentityProviderUpdate = ChainUpdate< + UpdateType.AddIdentityProvider, + AddIdentityProvider +>; + +/** An update to staking cooldown parameters */ +export type CooldownParametersUpdate = ChainUpdate< + UpdateType.CooldownParameters, + CooldownParameters +>; + +/** An update to time parameters */ +export type TimeParametersUpdate = ChainUpdate< + UpdateType.TimeParameters, + TimeParameters +>; + +/** An update holding a protocol update */ +export type ProtocolUpdate = ChainUpdate< + UpdateType.Protocol, + ProtocolUpdateDetails +>; + +/** An update to baker pool parameters */ +export type PoolParametersUpdate = ChainUpdate< + UpdateType.PoolParameters, + PoolParameters +>; + +/** An update to baker stake threshold parameters */ +export type BakerStakeThresholdUpdate = ChainUpdate< + UpdateType.BakerStakeThreshold, + BakerStakeThreshold +>; + +/** An update to timeout parameters, used from protocol version 6 */ +export type TimeoutParametersUpdate = ChainUpdate< + UpdateType.TimeoutParameters, + TimeoutParameters +>; + +/** An update to mininum time between blocks, used from protocol version 6 */ +export type MinBlockTimeUpdate = ChainUpdate; + +/** An update to maximum amount of energy per block, used from protocol version 6 */ +export type BlockEnergyLimitUpdate = ChainUpdate< + UpdateType.BlockEnergyLimit, + Energy +>; + +/** An update to finalization committee parameters, used from protocol version 6 */ +export type FinalizationCommitteeParametersUpdate = ChainUpdate< + UpdateType.FinalizationCommitteeParameters, + FinalizationCommitteeParameters +>; + +/** An update to level 1 key */ +export type Level1Update = ChainUpdate; + +/** An update to root key */ +export type RootUpdate = ChainUpdate; + +/** A pending update to higher level keys */ +export type PendingHigherLevelKeyUpdate = ChainUpdate< + UpdateType.HigherLevelKeyUpdate, + HigherLevelKeyUpdate +>; + +/** A pending update to authorization keys */ +export type PendingAuthorizationKeysUpdate = ChainUpdate< + UpdateType.AuthorizationKeysUpdate, + AuthorizationKeysUpdate +>; + +/** A union of chain updates, barring key updates */ export type CommonUpdate = | MicroCCDPerEuroUpdate | EuroPerEnergyUpdate @@ -158,13 +180,16 @@ export type CommonUpdate = | BlockEnergyLimitUpdate | FinalizationCommitteeParametersUpdate; +/** A union of chain updates */ export type UpdateInstructionPayload = CommonUpdate | RootUpdate | Level1Update; +/** A union of possible pending updates */ export type PendingUpdate = | CommonUpdate | PendingHigherLevelKeyUpdate | PendingAuthorizationKeysUpdate; +/** Chain update types */ export enum UpdateType { Root = 'root', Level1 = 'level1', From c745e11ef59e83a89eb7317b2624c5a368229679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 22 Jun 2023 16:10:47 +0200 Subject: [PATCH 33/41] Align protocol version types --- packages/common/CHANGELOG.md | 1 + packages/common/src/GRPCTypeTranslation.ts | 12 ++++++++---- packages/common/src/types.ts | 17 +++++++++++++---- packages/nodejs/src/client.ts | 2 -- packages/nodejs/test/getConsensusStatus.test.ts | 2 +- packages/nodejs/test/resources/expectedJsons.ts | 3 ++- 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 97b1315b9..87b452739 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -17,6 +17,7 @@ - `ElectionInfo` changed to `ElectionInfoV0 | ElectionInfoV1` - Renamed type `MicroGtuPerEuroUpdate` to `MicroCCDPerEuroUpdate` - Renamed enum member `UpdateType.MicroGtuPerEuro` to `UpdateType.MicroCCDPerEuro`, along with it's corresponding string value from `"microGtuPerEuro"` to `"microCCDPerEuro"`. +- Changed type of `protocolVersion` on `BlockInfo`, `RewardStatus`, and `ConsensusStatus` from `bigint` to `ProtocolVersion` to avoid confusion when translating from the GRPC enum type. ### Fixed diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index 7308c1dce..40f9d043c 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -651,12 +651,16 @@ export function passiveDelegationInfo( }; } +function translateProtocolVersion(pv: v2.ProtocolVersion): v1.ProtocolVersion { + return pv as number; +} + export function tokenomicsInfo(info: v2.TokenomicsInfo): v1.RewardStatus { switch (info.tokenomics.oneofKind) { case 'v0': { const v0 = info.tokenomics.v0; return { - protocolVersion: BigInt(v0.protocolVersion), + protocolVersion: translateProtocolVersion(v0.protocolVersion), totalAmount: unwrap(v0.totalAmount?.value), totalEncryptedAmount: unwrap(v0.totalEncryptedAmount?.value), bakingRewardAccount: unwrap(v0.bakingRewardAccount?.value), @@ -669,7 +673,7 @@ export function tokenomicsInfo(info: v2.TokenomicsInfo): v1.RewardStatus { case 'v1': { const v1 = info.tokenomics.v1; return { - protocolVersion: BigInt(v1.protocolVersion), + protocolVersion: translateProtocolVersion(v1.protocolVersion), totalAmount: unwrap(v1.totalAmount?.value), totalEncryptedAmount: unwrap(v1.totalEncryptedAmount?.value), bakingRewardAccount: unwrap(v1.bakingRewardAccount?.value), @@ -711,7 +715,7 @@ export function consensusInfo(ci: v2.ConsensusInfo): v1.ConsensusStatus { genesisTime: trTimestamp(ci.genesisTime), currentEraGenesisTime: trTimestamp(ci.currentEraGenesisTime), genesisIndex: unwrap(ci.genesisIndex?.value), - protocolVersion: BigInt(unwrap(ci.protocolVersion)), + protocolVersion: translateProtocolVersion(unwrap(ci.protocolVersion)), // Only include the following if they are not undefined ...(ci.blockReceivePeriodEma && { blockReceivePeriodEMA: ci.blockReceivePeriodEma, @@ -2305,7 +2309,7 @@ export function blockInfo(blockInfo: v2.BlockInfo): v1.BlockInfo { transactionEnergyCost: unwrap(blockInfo.transactionsEnergyCost?.value), genesisIndex: unwrap(blockInfo.genesisIndex?.value), eraBlockHeight: Number(unwrap(blockInfo.eraBlockHeight?.value)), - protocolVersion: BigInt(blockInfo.protocolVersion), + protocolVersion: translateProtocolVersion(blockInfo.protocolVersion), }; if (blockInfo.protocolVersion < v2.ProtocolVersion.PROTOCOL_VERSION_6) { diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 1854fdbf9..411a871da 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -58,6 +58,15 @@ export interface Versioned { value: T; } +export enum ProtocolVersion { + PV1, + PV2, + PV3, + PV4, + PV5, + PV6, +} + export enum AttributesKeys { firstName, lastName, @@ -684,7 +693,7 @@ export interface BlockSummaryV1 extends BlockSummaryCommon { export type BlockSummary = BlockSummaryV0 | BlockSummaryV1; interface RewardStatusCommon { - protocolVersion?: bigint; + protocolVersion?: ProtocolVersion; totalAmount: Amount; totalEncryptedAmount: Amount; bakingRewardAccount: Amount; @@ -699,7 +708,7 @@ export interface RewardStatusV1 extends RewardStatusCommon { nextPaydayTime: Date; nextPaydayMintRate: MintRate; totalStakedCapital: Amount; - protocolVersion: bigint; + protocolVersion: ProtocolVersion; } export type RewardStatus = RewardStatusV0 | RewardStatusV1; @@ -749,7 +758,7 @@ export interface BlockInfoCommon { /** The height of this block relative to the (re)genesis block of its era */ eraBlockHeight: number; /** The protocol version the block belongs to */ - protocolVersion: bigint; + protocolVersion: ProtocolVersion; } /** Block info used for protocol version 1-5 */ @@ -863,7 +872,7 @@ export interface ConsensusStatusCommon { genesisIndex: number; /** Currently active protocol version. */ - protocolVersion: bigint; + protocolVersion: ProtocolVersion; } /** Consensus status used for protocol version 1-5 */ diff --git a/packages/nodejs/src/client.ts b/packages/nodejs/src/client.ts index db3c223ca..7a2b3a022 100644 --- a/packages/nodejs/src/client.ts +++ b/packages/nodejs/src/client.ts @@ -504,7 +504,6 @@ export default class ConcordiumNodeClient { 'finalizationCount', 'blocksVerifiedCount', 'blocksReceivedCount', - 'protocolVersion', 'currentTimeoutDuration', 'currentRound', 'currentEpoch', @@ -701,7 +700,6 @@ export default class ConcordiumNodeClient { const dates: DateKey[] = ['nextPaydayTime']; const bigInts: BigIntKey[] = [ - 'protocolVersion', 'gasAccount', 'totalAmount', 'totalStakedCapital', diff --git a/packages/nodejs/test/getConsensusStatus.test.ts b/packages/nodejs/test/getConsensusStatus.test.ts index 241279cd0..bdbfca04d 100644 --- a/packages/nodejs/test/getConsensusStatus.test.ts +++ b/packages/nodejs/test/getConsensusStatus.test.ts @@ -61,7 +61,7 @@ test('retrieves the consensus status from the node with correct types', async () typeof consensusStatus.lastFinalizedBlockHeight === 'bigint' ).toBeTruthy(), expect( - typeof consensusStatus.protocolVersion === 'bigint' + typeof consensusStatus.protocolVersion === 'number' ).toBeTruthy(), ]); }); diff --git a/packages/nodejs/test/resources/expectedJsons.ts b/packages/nodejs/test/resources/expectedJsons.ts index fe8ab2b86..cfd78e01a 100644 --- a/packages/nodejs/test/resources/expectedJsons.ts +++ b/packages/nodejs/test/resources/expectedJsons.ts @@ -7,6 +7,7 @@ import { ElectionInfoV0, ModuleReference, NextUpdateSequenceNumbers, + ProtocolVersion, } from '@concordium/common-sdk'; export const accountInfo = { @@ -1782,7 +1783,7 @@ export const blockInfo: BlockInfoV0 = { transactionEnergyCost: 0n, genesisIndex: 1, eraBlockHeight: 1258806, - protocolVersion: 3n, + protocolVersion: ProtocolVersion.PV4, }; export const bakers = [ From 4bbb3a19633609bde15975f16f0042dcb1c34011 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Fri, 23 Jun 2023 11:01:31 +0200 Subject: [PATCH 34/41] Undo PV enum, align PV across grpcv1 and grpcv2 --- packages/common/CHANGELOG.md | 2 +- packages/common/src/GRPCTypeTranslation.ts | 4 +- packages/common/src/blockSummaryHelpers.ts | 33 +++++++++-- packages/common/src/types.ts | 56 +++++++++++++------ packages/common/src/versionedTypeHelpers.ts | 11 ---- packages/nodejs/src/client.ts | 4 ++ .../nodejs/test/getConsensusStatus.test.ts | 2 +- .../nodejs/test/resources/expectedJsons.ts | 3 +- 8 files changed, 75 insertions(+), 40 deletions(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 87b452739..8ae9d9d0d 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -17,11 +17,11 @@ - `ElectionInfo` changed to `ElectionInfoV0 | ElectionInfoV1` - Renamed type `MicroGtuPerEuroUpdate` to `MicroCCDPerEuroUpdate` - Renamed enum member `UpdateType.MicroGtuPerEuro` to `UpdateType.MicroCCDPerEuro`, along with it's corresponding string value from `"microGtuPerEuro"` to `"microCCDPerEuro"`. -- Changed type of `protocolVersion` on `BlockInfo`, `RewardStatus`, and `ConsensusStatus` from `bigint` to `ProtocolVersion` to avoid confusion when translating from the GRPC enum type. ### Fixed - Cost calculation for `deployModule` transaction. +- Fixed a bug where protocol version was different (i.e. 1 less than what it should be) when using the gRPCv2 API (compared to what is returned by the gRPCv1 API). ### Added diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index 40f9d043c..c67ac2658 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -651,8 +651,8 @@ export function passiveDelegationInfo( }; } -function translateProtocolVersion(pv: v2.ProtocolVersion): v1.ProtocolVersion { - return pv as number; +function translateProtocolVersion(pv: v2.ProtocolVersion): bigint { + return BigInt(pv + 1); // Protocol version enum indexes from 0, i.e. pv.PROTOCOL_VERSION_1 = 0. } export function tokenomicsInfo(info: v2.TokenomicsInfo): v1.RewardStatus { diff --git a/packages/common/src/blockSummaryHelpers.ts b/packages/common/src/blockSummaryHelpers.ts index 508be086b..3dc8fce06 100644 --- a/packages/common/src/blockSummaryHelpers.ts +++ b/packages/common/src/blockSummaryHelpers.ts @@ -2,20 +2,43 @@ import { BlockSummary, BlockSummaryV0, BlockSummaryV1, + BlockSummaryV2, + UpdateQueues, + UpdateQueuesV0, + UpdateQueuesV1, + UpdateQueuesV2, Updates, UpdatesV0, UpdatesV1, + UpdatesV2, } from './types'; -import { isUpdateQueuesV0, isUpdateQueuesV1 } from './versionedTypeHelpers'; -export const isUpdatesV1 = (u: Updates): u is UpdatesV1 => - isUpdateQueuesV1(u.updateQueues); +/** Whether {@link UpdateQueues} parameter given is of type {@link UpdateQueuesV0} */ +export const isUpdateQueuesV0 = (uq: UpdateQueues): uq is UpdateQueuesV0 => + (uq as UpdateQueuesV0).bakerStakeThreshold !== undefined; + +/** Whether {@link UpdateQueues} parameter given is of type {@link UpdateQueuesV1} */ +export const isUpdateQueuesV1 = (uq: UpdateQueues): uq is UpdateQueuesV1 => + (uq as UpdateQueuesV1).timeParameters !== undefined; + +/** Whether {@link UpdateQueues} parameter given is of type {@link UpdateQueuesV2} */ +export const isUpdateQueuesV2 = (uq: UpdateQueues): uq is UpdateQueuesV2 => + (uq as UpdateQueuesV2).timeoutParameters !== undefined; export const isUpdatesV0 = (u: Updates): u is UpdatesV0 => isUpdateQueuesV0(u.updateQueues); -export const isBlockSummaryV1 = (bs: BlockSummary): bs is BlockSummaryV1 => - bs.protocolVersion !== undefined && bs.protocolVersion > 3n; +export const isUpdatesV1 = (u: Updates): u is UpdatesV1 => + isUpdateQueuesV1(u.updateQueues); + +export const isUpdatesV2 = (u: Updates): u is UpdatesV2 => + isUpdateQueuesV2(u.updateQueues); export const isBlockSummaryV0 = (bs: BlockSummary): bs is BlockSummaryV0 => bs.protocolVersion === undefined || bs.protocolVersion <= 3n; + +export const isBlockSummaryV1 = (bs: BlockSummary): bs is BlockSummaryV1 => + bs.protocolVersion !== undefined && bs.protocolVersion > 3n; + +export const isBlockSummaryV2 = (bs: BlockSummary): bs is BlockSummaryV2 => + bs.protocolVersion !== undefined && bs.protocolVersion > 5n; diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 411a871da..8269e0107 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -58,15 +58,6 @@ export interface Versioned { value: T; } -export enum ProtocolVersion { - PV1, - PV2, - PV3, - PV4, - PV5, - PV6, -} - export enum AttributesKeys { firstName, lastName, @@ -615,7 +606,7 @@ export interface UpdateQueuesV0 extends UpdateQueuesCommon { } /** - * Used from protocol version 4 + * Used in protocol version 4 and 5 */ export interface UpdateQueuesV1 extends UpdateQueuesCommon { cooldownParameters: UpdateQueue; @@ -623,7 +614,17 @@ export interface UpdateQueuesV1 extends UpdateQueuesCommon { poolParameters: UpdateQueue; } -export type UpdateQueues = UpdateQueuesV0 | UpdateQueuesV1; +/** + * Used from protocol version 6 + */ +export interface UpdateQueuesV2 extends UpdateQueuesV1 { + timeoutParameters: UpdateQueue; + minBlockTime: UpdateQueue; + blockEnergyLimit: UpdateQueue; + finalizationCommiteeParameters: UpdateQueue; +} + +export type UpdateQueues = UpdateQueuesV0 | UpdateQueuesV1 | UpdateQueuesV2; interface ProtocolUpdate { message: string; @@ -657,9 +658,19 @@ export interface UpdatesV1 extends UpdatesCommon { } /** + * Used from protocol version 4 * @deprecated This is type describing return types from the JSON-RPC client and the V1 gRPC client, both of which have been deprecated */ -export type Updates = UpdatesV0 | UpdatesV1; +export interface UpdatesV2 extends UpdatesCommon { + chainParameters: ChainParametersV2; + updateQueues: UpdateQueuesV2; + keys: KeysV1; +} + +/** + * @deprecated This is type describing return types from the JSON-RPC client and the V1 gRPC client, both of which have been deprecated + */ +export type Updates = UpdatesV0 | UpdatesV1 | UpdatesV2; /** * @deprecated This is type describing return types from the JSON-RPC client and the V1 gRPC client, both of which have been deprecated @@ -679,7 +690,7 @@ export interface BlockSummaryV0 extends BlockSummaryCommon { } /** - * Used from protocol version 4 + * Used in protocol version 4 and 5 * @deprecated This is type describing return types from the JSON-RPC client and the V1 gRPC client, both of which have been deprecated */ export interface BlockSummaryV1 extends BlockSummaryCommon { @@ -687,13 +698,22 @@ export interface BlockSummaryV1 extends BlockSummaryCommon { protocolVersion: bigint; } +/** + * Used from protocol version 6 + * @deprecated This is type describing return types from the JSON-RPC client and the V1 gRPC client, both of which have been deprecated + */ +export interface BlockSummaryV2 extends BlockSummaryCommon { + updates: UpdatesV2; + protocolVersion: bigint; +} + /** * @deprecated This is type describing return types from the JSON-RPC client and the V1 gRPC client, both of which have been deprecated */ -export type BlockSummary = BlockSummaryV0 | BlockSummaryV1; +export type BlockSummary = BlockSummaryV0 | BlockSummaryV1 | BlockSummaryV2; interface RewardStatusCommon { - protocolVersion?: ProtocolVersion; + protocolVersion?: bigint; totalAmount: Amount; totalEncryptedAmount: Amount; bakingRewardAccount: Amount; @@ -708,7 +728,7 @@ export interface RewardStatusV1 extends RewardStatusCommon { nextPaydayTime: Date; nextPaydayMintRate: MintRate; totalStakedCapital: Amount; - protocolVersion: ProtocolVersion; + protocolVersion: bigint; } export type RewardStatus = RewardStatusV0 | RewardStatusV1; @@ -758,7 +778,7 @@ export interface BlockInfoCommon { /** The height of this block relative to the (re)genesis block of its era */ eraBlockHeight: number; /** The protocol version the block belongs to */ - protocolVersion: ProtocolVersion; + protocolVersion: bigint; } /** Block info used for protocol version 1-5 */ @@ -872,7 +892,7 @@ export interface ConsensusStatusCommon { genesisIndex: number; /** Currently active protocol version. */ - protocolVersion: ProtocolVersion; + protocolVersion: bigint; } /** Consensus status used for protocol version 1-5 */ diff --git a/packages/common/src/versionedTypeHelpers.ts b/packages/common/src/versionedTypeHelpers.ts index 257c7c796..fe9fcac30 100644 --- a/packages/common/src/versionedTypeHelpers.ts +++ b/packages/common/src/versionedTypeHelpers.ts @@ -23,9 +23,6 @@ import { StakePendingChange, StakePendingChangeV0, StakePendingChangeV1, - UpdateQueues, - UpdateQueuesV0, - UpdateQueuesV1, } from './types'; /** Whether {@link AccountInfo} parameter given is of type {@link AccountInfoBakerV0} */ @@ -81,14 +78,6 @@ export const isKeysV0 = (ks: Keys): ks is KeysV0 => export const isKeysV1 = (ks: Keys): ks is KeysV1 => isAuthorizationsV1(ks.level2Keys); -/** Whether {@link UpdateQueues} parameter given is of type {@link UpdateQueuesV0} */ -export const isUpdateQueuesV0 = (uq: UpdateQueues): uq is UpdateQueuesV0 => - (uq as UpdateQueuesV0).bakerStakeThreshold !== undefined; - -/** Whether {@link UpdateQueues} parameter given is of type {@link UpdateQueuesV1} */ -export const isUpdateQueuesV1 = (uq: UpdateQueues): uq is UpdateQueuesV1 => - (uq as UpdateQueuesV1).timeParameters !== undefined; - /** Whether {@link BlockInfo} parameter given is of type {@link BlockInfoV0} */ export const isBlockInfoV0 = (bi: BlockInfo): bi is BlockInfoV0 => (bi as BlockInfoV0).blockSlot !== undefined; diff --git a/packages/nodejs/src/client.ts b/packages/nodejs/src/client.ts index 7a2b3a022..26fd0886e 100644 --- a/packages/nodejs/src/client.ts +++ b/packages/nodejs/src/client.ts @@ -361,6 +361,7 @@ export default class ConcordiumNodeClient { | keyof FinalizationData | keyof TransactionSummary | keyof (ChainParametersV0 & ChainParametersV1 & ChainParametersV2) + | keyof BlockSummary | keyof PoolParametersV1 | keyof CooldownParametersV1 | keyof TimeParametersV1 @@ -388,6 +389,7 @@ export default class ConcordiumNodeClient { 'amount', 'index', 'subindex', + 'protocolVersion', // v0 keys 'bakerCooldownEpochs', @@ -504,6 +506,7 @@ export default class ConcordiumNodeClient { 'finalizationCount', 'blocksVerifiedCount', 'blocksReceivedCount', + 'protocolVersion', 'currentTimeoutDuration', 'currentRound', 'currentEpoch', @@ -700,6 +703,7 @@ export default class ConcordiumNodeClient { const dates: DateKey[] = ['nextPaydayTime']; const bigInts: BigIntKey[] = [ + 'protocolVersion', 'gasAccount', 'totalAmount', 'totalStakedCapital', diff --git a/packages/nodejs/test/getConsensusStatus.test.ts b/packages/nodejs/test/getConsensusStatus.test.ts index bdbfca04d..241279cd0 100644 --- a/packages/nodejs/test/getConsensusStatus.test.ts +++ b/packages/nodejs/test/getConsensusStatus.test.ts @@ -61,7 +61,7 @@ test('retrieves the consensus status from the node with correct types', async () typeof consensusStatus.lastFinalizedBlockHeight === 'bigint' ).toBeTruthy(), expect( - typeof consensusStatus.protocolVersion === 'number' + typeof consensusStatus.protocolVersion === 'bigint' ).toBeTruthy(), ]); }); diff --git a/packages/nodejs/test/resources/expectedJsons.ts b/packages/nodejs/test/resources/expectedJsons.ts index cfd78e01a..68699978b 100644 --- a/packages/nodejs/test/resources/expectedJsons.ts +++ b/packages/nodejs/test/resources/expectedJsons.ts @@ -7,7 +7,6 @@ import { ElectionInfoV0, ModuleReference, NextUpdateSequenceNumbers, - ProtocolVersion, } from '@concordium/common-sdk'; export const accountInfo = { @@ -1783,7 +1782,7 @@ export const blockInfo: BlockInfoV0 = { transactionEnergyCost: 0n, genesisIndex: 1, eraBlockHeight: 1258806, - protocolVersion: ProtocolVersion.PV4, + protocolVersion: 4n, }; export const bakers = [ From 5db2ea840c079d4e105c7724bfe9cf0795c29fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Fri, 23 Jun 2023 11:51:49 +0200 Subject: [PATCH 35/41] web/nodejs changelog updates --- packages/common/src/types.ts | 4 ++-- packages/nodejs/CHANGELOG.md | 1 + packages/web/CHANGELOG.md | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 8269e0107..5ae3b0913 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -648,7 +648,7 @@ export interface UpdatesV0 extends UpdatesCommon { } /** - * Used from protocol version 4 + * Used in protocol version 4 and 5 * @deprecated This is type describing return types from the JSON-RPC client and the V1 gRPC client, both of which have been deprecated */ export interface UpdatesV1 extends UpdatesCommon { @@ -658,7 +658,7 @@ export interface UpdatesV1 extends UpdatesCommon { } /** - * Used from protocol version 4 + * Used from protocol version 6 * @deprecated This is type describing return types from the JSON-RPC client and the V1 gRPC client, both of which have been deprecated */ export interface UpdatesV2 extends UpdatesCommon { diff --git a/packages/nodejs/CHANGELOG.md b/packages/nodejs/CHANGELOG.md index 653b4b27b..7c0d4d33a 100644 --- a/packages/nodejs/CHANGELOG.md +++ b/packages/nodejs/CHANGELOG.md @@ -6,6 +6,7 @@ - Bumped @concordium/common-sdk to 8.0.0: - Properly formed errors thrown by functions wrapping WASM execution (from @concordium/rust-bindings) with more helpful error messages. + - Types adapted to changes in protocol version 6. - and [more](../common/CHANGELOG.md) ## 7.0.0 2023-05-15 diff --git a/packages/web/CHANGELOG.md b/packages/web/CHANGELOG.md index fafee8697..91e271dc9 100644 --- a/packages/web/CHANGELOG.md +++ b/packages/web/CHANGELOG.md @@ -7,6 +7,7 @@ - Bumped @concordium/rust-bindings to 1.0.0. (Throws proper `Error`s when execution fails for any WASM entrypoint, with improved error messages) - Bumped @concordium/common-sdk to 8.0.0: - Properly formed errors thrown by functions wrapping WASM execution (from @concordium/rust-bindings) with more helpful error messages. + - Types adapted to changes in protocol version 6. - and [more](../common/CHANGELOG.md) ## 4.0.1 2023-05-25 From c622d3b23ebe9382a3cfdb107988c80c6ef711b9 Mon Sep 17 00:00:00 2001 From: Michael Bisgaard Olesen Date: Fri, 23 Jun 2023 12:08:14 +0200 Subject: [PATCH 36/41] Name gRPC client (v2) consistently (#191) Rename ConcordiumNodeClient to ConcordiumGRPCClient as that's the name under which it's exported. The name ConcordiumNodeClient is used only internally within common-sdk. The renaming is done only for the v2 client. --------- Co-authored-by: Hjort --- .markdown-linkcheck.json | 4 ++-- packages/common/src/GRPCClient.ts | 8 ++++---- packages/common/src/JsonRpcClient.ts | 2 +- packages/common/src/cis0.ts | 12 ++++++------ packages/common/src/cis2/CIS2Contract.ts | 10 +++++----- packages/common/src/index.ts | 2 +- packages/nodejs/README.md | 2 +- packages/nodejs/src/clientV2.ts | 2 +- packages/nodejs/test/clientV2.test.ts | 5 +++-- packages/nodejs/test/testHelpers.ts | 5 ++--- packages/web/README.md | 5 ++--- pages/cis2-contracts.md | 6 +++--- pages/documentation.md | 2 +- pages/misc-pages/grpc-v1.md | 2 +- pages/utility-functions.md | 4 ++-- 15 files changed, 35 insertions(+), 36 deletions(-) diff --git a/.markdown-linkcheck.json b/.markdown-linkcheck.json index e5088a3cc..84e981113 100644 --- a/.markdown-linkcheck.json +++ b/.markdown-linkcheck.json @@ -1,7 +1,7 @@ { "ignorePatterns": [ { - "pattern": "classes/Common_GRPC_Client.ConcordiumNodeClient.html" + "pattern": "classes/Common_GRPC_Client.ConcordiumGRPCClient.html" } ] -} \ No newline at end of file +} diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index 091bb9985..1569caf23 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1,6 +1,6 @@ /** * This is the GRPC-Client used by both the Web-SDK and the NodeJS-SDK. Check - * out the {@link ConcordiumNodeClient} + * out the {@link ConcordiumGRPCClient} * * @module Common GRPC-Client */ @@ -45,10 +45,10 @@ export type FindInstanceCreationReponse = { * A concordium-node specific gRPC client wrapper. * * @example - * import ConcordiumNodeClient from "..." - * const client = new ConcordiumNodeClient('127.0.0.1', 20000, credentials, metadata, 15000); + * import { ConcordiumGRPCClient } from "..." + * const client = new ConcordiumGRPCClient('127.0.0.1', 20000, credentials, metadata, 15000); */ -export default class ConcordiumNodeClient { +export class ConcordiumGRPCClient { client: QueriesClient; /** diff --git a/packages/common/src/JsonRpcClient.ts b/packages/common/src/JsonRpcClient.ts index 0323911cf..91ece9bbd 100644 --- a/packages/common/src/JsonRpcClient.ts +++ b/packages/common/src/JsonRpcClient.ts @@ -47,7 +47,7 @@ function transformJsonResponse( } /** - * @deprecated This has been deprecated in favor of the {@link ConcordiumNodeClient} that uses version 2 of the concordium gRPC API + * @deprecated This has been deprecated in favor of the {@link ConcordiumGRPCClient} that uses version 2 of the concordium gRPC API */ export class JsonRpcClient { provider: Provider; diff --git a/packages/common/src/cis0.ts b/packages/common/src/cis0.ts index f1b550fe0..056c4a077 100644 --- a/packages/common/src/cis0.ts +++ b/packages/common/src/cis0.ts @@ -1,6 +1,6 @@ import { Buffer } from 'buffer/'; import { ContractAddress, HexString } from './types'; -import ConcordiumNodeClient from './GRPCClient'; +import { ConcordiumGRPCClient } from './GRPCClient'; import { encodeWord16, makeDeserializeListResponse, @@ -100,7 +100,7 @@ const deserializeSupportResult = /** * Queries a CIS-0 contract for support for a {@link CIS0.StandardIdentifier}. * - * @param {ConcordiumNodeClient} grpcClient - The client to be used for the query. + * @param {ConcordiumGRPCClient} grpcClient - The client to be used for the query. * @param {ContractAddress} contractAddress - The address of the contract to query. * @param {CIS0.StandardIdentifier} standardId - The standard identifier to query for support in contract. * @param {HexString} [blockHash] - The hash of the block to query at. @@ -110,7 +110,7 @@ const deserializeSupportResult = * @returns {CIS0.SupportResult} The support result of the query, or `undefined` if the contract does not support CIS-0. */ export function cis0Supports( - grpcClient: ConcordiumNodeClient, + grpcClient: ConcordiumGRPCClient, contractAddress: ContractAddress, standardId: CIS0.StandardIdentifier, blockHash?: HexString @@ -118,7 +118,7 @@ export function cis0Supports( /** * Queries a CIS-0 contract for support for a {@link CIS0.StandardIdentifier}. * - * @param {ConcordiumNodeClient} grpcClient - The client to be used for the query. + * @param {ConcordiumGRPCClient} grpcClient - The client to be used for the query. * @param {ContractAddress} contractAddress - The address of the contract to query. * @param {CIS0.StandardIdentifier[]} standardIds - The standard identifiers to query for support in contract. * @param {HexString} [blockHash] - The hash of the block to query at. @@ -128,13 +128,13 @@ export function cis0Supports( * @returns {CIS0.SupportResult[]} The support results of the query ordered by the ID's supplied by the `ids` param, or `undefined` if the contract does not support CIS-0. */ export function cis0Supports( - grpcClient: ConcordiumNodeClient, + grpcClient: ConcordiumGRPCClient, contractAddress: ContractAddress, standardIds: CIS0.StandardIdentifier[], blockHash?: HexString ): Promise; export async function cis0Supports( - grpcClient: ConcordiumNodeClient, + grpcClient: ConcordiumGRPCClient, contractAddress: ContractAddress, standardIds: CIS0.StandardIdentifier | CIS0.StandardIdentifier[], blockHash?: HexString diff --git a/packages/common/src/cis2/CIS2Contract.ts b/packages/common/src/cis2/CIS2Contract.ts index 89ed7d807..17de23169 100644 --- a/packages/common/src/cis2/CIS2Contract.ts +++ b/packages/common/src/cis2/CIS2Contract.ts @@ -6,7 +6,7 @@ import { InvokeContractResult, UpdateContractPayload, } from '../types'; -import ConcordiumNodeClient from '../GRPCClient'; +import { ConcordiumGRPCClient } from '../GRPCClient'; import { AccountSigner, signTransaction } from '../signHelpers'; import { serializeCIS2Transfers, @@ -52,7 +52,7 @@ const getDefaultExpiryDate = (): Date => { */ class CIS2DryRun { constructor( - private grpcClient: ConcordiumNodeClient, + private grpcClient: ConcordiumGRPCClient, private contractAddress: ContractAddress, private contractName: string ) {} @@ -163,7 +163,7 @@ export class CIS2Contract { private dryRunInstance: CIS2DryRun; constructor( - private grpcClient: ConcordiumNodeClient, + private grpcClient: ConcordiumGRPCClient, private contractAddress: ContractAddress, private contractName: string ) { @@ -177,14 +177,14 @@ export class CIS2Contract { /** * Creates a new `CIS2Contract` instance by querying the node for the necessary information through the supplied `grpcClient`. * - * @param {ConcordiumNodeClient} grpcClient - The client used for contract invocations and updates. + * @param {ConcordiumGRPCClient} grpcClient - The client used for contract invocations and updates. * @param {ContractAddress} contractAddress - Address of the contract instance. * * @throws If `InstanceInfo` could not be received for the contract, if the contract does not support the CIS-2 standard, * or if the contract name could not be parsed from the information received from the node. */ static async create( - grpcClient: ConcordiumNodeClient, + grpcClient: ConcordiumGRPCClient, contractAddress: ContractAddress ): Promise { const instanceInfo = await grpcClient.getInstanceInfo(contractAddress); diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index ef0550e90..4b349166e 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -48,7 +48,7 @@ export { isHex, streamToList, wasmToSchema, unwrap } from './util'; export { HttpProvider } from './providers/httpProvider'; export { JsonRpcClient } from './JsonRpcClient'; export * from './identity'; -export { default as ConcordiumGRPCClient } from './GRPCClient'; +export { ConcordiumGRPCClient } from './GRPCClient'; export { getAccountTransactionHandler } from './accountTransactions'; export * from './energyCost'; diff --git a/packages/nodejs/README.md b/packages/nodejs/README.md index 33dac37a9..903c9b681 100644 --- a/packages/nodejs/README.md +++ b/packages/nodejs/README.md @@ -8,7 +8,7 @@ Please see the [documentation](https://developer.concordium.software/concordium-node-sdk-js/index.html) for more information -## ConcordiumNodeClient +## ConcordiumGRPCClient The SDK provides a gRPC client, which can interact with the [Concordium Node](https://github.com/Concordium/concordium-node) diff --git a/packages/nodejs/src/clientV2.ts b/packages/nodejs/src/clientV2.ts index 61ac54701..cb2ac0303 100644 --- a/packages/nodejs/src/clientV2.ts +++ b/packages/nodejs/src/clientV2.ts @@ -1,6 +1,6 @@ import { ChannelCredentials } from '@grpc/grpc-js'; import { GrpcOptions, GrpcTransport } from '@protobuf-ts/grpc-transport'; -import ConcordiumGRPCClient from '@concordium/common-sdk/lib/GRPCClient'; +import { ConcordiumGRPCClient } from '@concordium/common-sdk/lib/GRPCClient'; /** * Initialize a gRPC client for a specific concordium node. diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index 569fc7580..5de495a57 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -1,7 +1,8 @@ import * as v1 from '@concordium/common-sdk'; import * as v2 from '../../common/grpc/v2/concordium/types'; import { testnetBulletproofGenerators } from './resources/bulletproofgenerators'; -import ConcordiumNodeClientV2, { +import { + ConcordiumGRPCClient, getAccountIdentifierInput, getBlockHashInput, } from '@concordium/common-sdk/lib/GRPCClient'; @@ -56,7 +57,7 @@ const testBlockHash = // Retrieves the account info for the given account in the GRPCv2 type format. function getAccountInfoV2( - client: ConcordiumNodeClientV2, + client: ConcordiumGRPCClient, accountIdentifier: v1.AccountIdentifierInput ): Promise { const accountInfoRequest = { diff --git a/packages/nodejs/test/testHelpers.ts b/packages/nodejs/test/testHelpers.ts index 32cd47aba..d69fd3094 100644 --- a/packages/nodejs/test/testHelpers.ts +++ b/packages/nodejs/test/testHelpers.ts @@ -5,7 +5,6 @@ import { ConcordiumGRPCClient, IdentityInput } from '@concordium/common-sdk'; import { decryptMobileWalletExport, EncryptedData } from '../src/wallet/crypto'; import { MobileWalletExport } from '../src/wallet/types'; import { createConcordiumClient } from '../src/clientV2'; -import ConcordiumNodeClientV2 from '@concordium/common-sdk/lib/GRPCClient'; import { GrpcWebFetchTransport } from '@protobuf-ts/grpcweb-transport'; // This makes sure the necessary types are added to `globalThis` @@ -20,7 +19,7 @@ export { getModuleBuffer } from '../src/util'; export function getNodeClient( address = 'node.testnet.concordium.com', port = 20000 -): ConcordiumNodeClientV2 { +): ConcordiumGRPCClient { return createConcordiumClient(address, port, credentials.createInsecure(), { timeout: 15000, }); @@ -29,7 +28,7 @@ export function getNodeClient( export function getNodeClientWeb( address = 'http://node.testnet.concordium.com', port = 20000 -): ConcordiumNodeClientV2 { +): ConcordiumGRPCClient { const transport = new GrpcWebFetchTransport({ baseUrl: `${address}:${port}`, timeout: 15000, diff --git a/packages/web/README.md b/packages/web/README.md index 34ebe50d0..b0c593143 100644 --- a/packages/web/README.md +++ b/packages/web/README.md @@ -12,7 +12,7 @@ for more information - [concordium-web-sdk](#concordium-web-sdk) - - [ConcordiumNodeClient](#concordiumnodeclient) + - [ConcordiumGRPCClient](#concordiumgrpcclient) - [JSON-RPC client](#json-rpc-client) - [Creating buffers](#creating-buffers) - [Examples](#examples) @@ -29,8 +29,7 @@ for more information - [SendCIS2UpdateOperator.html](#sendcis2updateoperatorhtml) -## ConcordiumNodeClient - +## ConcordiumGRPCClient The SDK provides a gRPC client, which can interact with the [Concordium Node](https://github.com/Concordium/concordium-node) using gRPC-web. diff --git a/pages/cis2-contracts.md b/pages/cis2-contracts.md index 64c98da3a..b05a0e713 100644 --- a/pages/cis2-contracts.md +++ b/pages/cis2-contracts.md @@ -21,19 +21,19 @@ This document describes the helper class for working with CIS-2 contracts ## CIS2Contract The CIS2Contract class wraps the -[ConcordiumNodeClient](../classes/Common_GRPC_Client.ConcordiumNodeClient.html), +[ConcordiumGRPCClient](../classes/Common_GRPC_Client.ConcordiumGRPCClient.html), defining an interface matching the [CIS-2 standard](https://proposals.concordium.software/CIS/cis-2.html). ### Creating a CIS2Contract -The contract relies on a `ConcordiumNodeClient` instance to communicate +The contract relies on a `ConcordiumGRPCClient` instance to communicate with the node along with a contract address of the CIS-2 contract to invoke functions on. ```ts const contractAddress = {index: 1234n, subindex: 0n}; - const contract = await CIS2Contract.create(nodeClient, contractAddress); // Implied that you already have a `ConcordiumNodeClient` instance of some form. + const contract = await CIS2Contract.create(nodeClient, contractAddress); // Implied that you already have a `ConcordiumGRPCClient` instance of some form. ``` This gets the relevant contract information from the node and checks diff --git a/pages/documentation.md b/pages/documentation.md index a2f1641ee..8a073092a 100644 --- a/pages/documentation.md +++ b/pages/documentation.md @@ -2,7 +2,7 @@ This is the documentation for the Concordium Javascript SDK. Here we cover the JS wrappers for interacting with the Concordium nodes. Most functionality is provideded by the -[GRPC-Client](../classes/Common_GRPC_Client.ConcordiumNodeClient.html) +[GRPC-Client](../classes/Common_GRPC_Client.ConcordiumGRPCClient.html) however there exists additional helper functions, for example to help with creating {@page transactions.md transactions}, or {@page identity-proofs.md creating identity proof statements}, or {@page utility-functions.md general diff --git a/pages/misc-pages/grpc-v1.md b/pages/misc-pages/grpc-v1.md index 6081c41a4..fde400114 100644 --- a/pages/misc-pages/grpc-v1.md +++ b/pages/misc-pages/grpc-v1.md @@ -1,5 +1,5 @@ > :warning: **This explains behaviour of the deprecated v1 concordium client**: -check out [the documentation the v2 client](../../classes/Common_GRPC_Client.ConcordiumNodeClient.html) +check out [the documentation the v2 client](../../classes/Common_GRPC_Client.ConcordiumGRPCClient.html) This describes the JSON-RPC client, which can interact with the [Concordium JSON-RPC server](https://github.com/Concordium/concordium-json-rpc) diff --git a/pages/utility-functions.md b/pages/utility-functions.md index 371852196..a85303da6 100644 --- a/pages/utility-functions.md +++ b/pages/utility-functions.md @@ -233,10 +233,10 @@ and does not give any guarantees for whether the contract adheres to the standard it claims to implement. The function returns `undefined` if the contract does not support CIS-0. -This requires a [`ConcordiumNodeClient`](../classes/Common_GRPC_Client.ConcordiumNodeClient.html). +This requires a [`ConcordiumGRPCClient`](../classes/Common_GRPC_Client.ConcordiumGRPCClient.html). ```ts - const client = ...; // `ConcordiumNodeClient` + const client = ...; // `ConcordiumGRPCClient` const address = {index: 1234n, subindex: 0n}; // Contract to check for support. const standardId = 'CIS-2'; // const standardIds = ['CIS-1', 'CIS-2']; // Example of a list of standards to check for. From aecb0484597d2cdab013a43ee8f190062a8b3ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Fri, 23 Jun 2023 12:46:31 +0200 Subject: [PATCH 37/41] Ensure types remain compatible with gRPC v1 API --- examples/client/getBlockChainParameters.ts | 5 +- packages/common/CHANGELOG.md | 7 - packages/common/src/GRPCTypeTranslation.ts | 327 +++++++++--------- packages/common/src/JsonRpcClient.ts | 11 +- packages/common/src/blockSummaryHelpers.ts | 6 +- packages/common/src/energyCost.ts | 6 +- packages/common/src/types.ts | 87 ++--- packages/common/src/types/chainUpdate.ts | 8 +- packages/common/src/versionedTypeHelpers.ts | 9 +- packages/nodejs/src/client.ts | 12 +- packages/nodejs/test/CIS2Contract.test.ts | 2 +- packages/nodejs/test/cis0.test.ts | 2 +- packages/nodejs/test/client.test.ts | 291 ++++++++++++++++ packages/nodejs/test/clientV2.test.ts | 4 +- packages/nodejs/test/events.test.ts | 2 +- .../nodejs/test/getConsensusStatus.test.ts | 2 +- packages/nodejs/test/manualTests.test.ts | 2 +- packages/nodejs/test/rejectReasons.test.ts | 2 +- .../nodejs/test/resources/expectedJsons.ts | 82 +++-- packages/nodejs/test/specialEvents.test.ts | 2 +- packages/nodejs/test/testHelpers.ts | 29 +- 21 files changed, 596 insertions(+), 302 deletions(-) create mode 100644 packages/nodejs/test/client.test.ts diff --git a/examples/client/getBlockChainParameters.ts b/examples/client/getBlockChainParameters.ts index 2ae9d7a15..c87cd1e71 100644 --- a/examples/client/getBlockChainParameters.ts +++ b/examples/client/getBlockChainParameters.ts @@ -62,10 +62,7 @@ const client = createConcordiumClient( if (isChainParametersV2(cp)) { console.log('Minimum block time', cp.consensusParameters.minBlockTime); } else if (isChainParametersV1(cp)) { - console.log( - 'Minimum equity capital:', - cp.poolParameters.minimumEquityCapital - ); + console.log('Minimum equity capital:', cp.minimumEquityCapital); } else { console.log( 'Chain parameters is V0 and does not contain information on minimum equity capital' diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index aec97093e..da6637c64 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -7,16 +7,9 @@ - Bumped @concordium/rust-bindings to 1.0.0. (Throws proper `Error`s when execution fails for any WASM entrypoint, with improved error messages) - Updated `types.ts` to conform to updated GRPC API, which includes adding more variants to existing types (all new variants take effect from protocol version 6): - `ChainParametersV2` added to `ChainParameters` - - `ChainParameters` field `microGTUPerEuro` is now called `microCCDPerEuro`. - - The following parameters on `ChainParametersV1` have been moved into objects to align with GRPC api: - - `passiveFinalizationCommission`, `passiveBakingCommission`, `passiveTransactionCommission`, `finalizationCommissionRange`, `bakingCommissionRange`, `transactionCommissionRange`, `minimumEquityCapital`, `capitalBound`, `leverageBound` have been moved to `poolParameters` - - `poolOwnerCooldown`, `delegatorCooldown` have been moved to `cooldownParameters` - - `rewardPeriodLength`, `mintPerPayday` have been moved to `timeParameters` - `BlockInfo` changed to `BlockInfoV0 | BlockInfoV1` - `ConsensusStatus` changed to `ConsensusStatusV0 | ConsensusStatusV1` - `ElectionInfo` changed to `ElectionInfoV0 | ElectionInfoV1` -- Renamed type `MicroGtuPerEuroUpdate` to `MicroCCDPerEuroUpdate` -- Renamed enum member `UpdateType.MicroGtuPerEuro` to `UpdateType.MicroCCDPerEuro`, along with it's corresponding string value from `"microGtuPerEuro"` to `"microCCDPerEuro"`. ### Fixed diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index c67ac2658..02a343074 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -255,7 +255,7 @@ function translateChainParametersCommon( ): v1.ChainParametersCommon { return { euroPerEnergy: unwrap(params.euroPerEnergy?.value), - microCCDPerEuro: unwrap(params.microCcdPerEuro?.value), + microGTUPerEuro: unwrap(params.microCcdPerEuro?.value), accountCreationLimit: unwrap(params.accountCreationLimit?.value), foundationAccount: unwrapToBase58(params.foundationAccount), }; @@ -404,24 +404,30 @@ function trChainParametersV0(v0: v2.ChainParametersV0): v1.ChainParametersV0 { const commonRewardParameters = translateRewardParametersCommon(v0); return { ...common, - ...commonRewardParameters, electionDifficulty: trAmountFraction(v0.electionDifficulty?.value), bakerCooldownEpochs: unwrap(v0.bakerCooldownEpochs?.value), minimumThresholdForBaking: unwrap(v0.minimumThresholdForBaking?.value), - gasRewards: { - baker: trAmountFraction(v0.gasRewards?.baker), - finalizationProof: trAmountFraction( - v0.gasRewards?.finalizationProof - ), - accountCreation: trAmountFraction(v0.gasRewards?.accountCreation), - chainUpdate: trAmountFraction(v0.gasRewards?.chainUpdate), - }, - mintDistribution: { - bakingReward: trAmountFraction(v0.mintDistribution?.bakingReward), - finalizationReward: trAmountFraction( - v0.mintDistribution?.finalizationReward - ), - mintPerSlot: trMintRate(v0.mintDistribution?.mintPerSlot), + rewardParameters: { + ...commonRewardParameters, + gASRewards: { + baker: trAmountFraction(v0.gasRewards?.baker), + finalizationProof: trAmountFraction( + v0.gasRewards?.finalizationProof + ), + accountCreation: trAmountFraction( + v0.gasRewards?.accountCreation + ), + chainUpdate: trAmountFraction(v0.gasRewards?.chainUpdate), + }, + mintDistribution: { + bakingReward: trAmountFraction( + v0.mintDistribution?.bakingReward + ), + finalizationReward: trAmountFraction( + v0.mintDistribution?.finalizationReward + ), + mintPerSlot: trMintRate(v0.mintDistribution?.mintPerSlot), + }, }, }; } @@ -433,66 +439,62 @@ function trChainParametersV1( const commonRewardParameters = translateRewardParametersCommon(params); return { ...common, - ...commonRewardParameters, electionDifficulty: trAmountFraction(params.electionDifficulty?.value), - timeParameters: { - rewardPeriodLength: unwrap( - params.timeParameters?.rewardPeriodLength?.value?.value - ), - mintPerPayday: trMintRate(params.timeParameters?.mintPerPayday), - }, - cooldownParameters: { - delegatorCooldown: unwrap( - params.cooldownParameters?.delegatorCooldown?.value - ), - poolOwnerCooldown: unwrap( - params.cooldownParameters?.poolOwnerCooldown?.value - ), - }, - poolParameters: { - passiveFinalizationCommission: trAmountFraction( - params.poolParameters?.passiveFinalizationCommission - ), - passiveBakingCommission: trAmountFraction( - params.poolParameters?.passiveBakingCommission - ), - passiveTransactionCommission: trAmountFraction( - params.poolParameters?.passiveTransactionCommission - ), - finalizationCommissionRange: translateCommissionRange( - params.poolParameters?.commissionBounds?.finalization - ), - bakingCommissionRange: translateCommissionRange( - params.poolParameters?.commissionBounds?.baking - ), - transactionCommissionRange: translateCommissionRange( - params.poolParameters?.commissionBounds?.transaction - ), - minimumEquityCapital: unwrap( - params.poolParameters?.minimumEquityCapital?.value - ), - capitalBound: trAmountFraction( - params.poolParameters?.capitalBound?.value - ), - leverageBound: unwrap(params.poolParameters?.leverageBound?.value), - }, - gasRewards: { - baker: trAmountFraction(params.gasRewards?.baker), - finalizationProof: trAmountFraction( - params.gasRewards?.finalizationProof - ), - accountCreation: trAmountFraction( - params.gasRewards?.accountCreation - ), - chainUpdate: trAmountFraction(params.gasRewards?.chainUpdate), - }, - mintDistribution: { - bakingReward: trAmountFraction( - params.mintDistribution?.bakingReward - ), - finalizationReward: trAmountFraction( - params.mintDistribution?.finalizationReward - ), + rewardPeriodLength: unwrap( + params.timeParameters?.rewardPeriodLength?.value?.value + ), + mintPerPayday: trMintRate(params.timeParameters?.mintPerPayday), + delegatorCooldown: unwrap( + params.cooldownParameters?.delegatorCooldown?.value + ), + poolOwnerCooldown: unwrap( + params.cooldownParameters?.poolOwnerCooldown?.value + ), + passiveFinalizationCommission: trAmountFraction( + params.poolParameters?.passiveFinalizationCommission + ), + passiveBakingCommission: trAmountFraction( + params.poolParameters?.passiveBakingCommission + ), + passiveTransactionCommission: trAmountFraction( + params.poolParameters?.passiveTransactionCommission + ), + finalizationCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.finalization + ), + bakingCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.baking + ), + transactionCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.transaction + ), + minimumEquityCapital: unwrap( + params.poolParameters?.minimumEquityCapital?.value + ), + capitalBound: trAmountFraction( + params.poolParameters?.capitalBound?.value + ), + leverageBound: unwrap(params.poolParameters?.leverageBound?.value), + rewardParameters: { + ...commonRewardParameters, + gASRewards: { + baker: trAmountFraction(params.gasRewards?.baker), + finalizationProof: trAmountFraction( + params.gasRewards?.finalizationProof + ), + accountCreation: trAmountFraction( + params.gasRewards?.accountCreation + ), + chainUpdate: trAmountFraction(params.gasRewards?.chainUpdate), + }, + mintDistribution: { + bakingReward: trAmountFraction( + params.mintDistribution?.bakingReward + ), + finalizationReward: trAmountFraction( + params.mintDistribution?.finalizationReward + ), + }, }, }; } @@ -505,97 +507,82 @@ function trChainParametersV2( return { ...common, - ...commonRewardParameters, - timeParameters: { - rewardPeriodLength: unwrap( - params.timeParameters?.rewardPeriodLength?.value?.value - ), - mintPerPayday: trMintRate(params.timeParameters?.mintPerPayday), - }, - cooldownParameters: { - delegatorCooldown: unwrap( - params.cooldownParameters?.delegatorCooldown?.value - ), - poolOwnerCooldown: unwrap( - params.cooldownParameters?.poolOwnerCooldown?.value - ), - }, - poolParameters: { - passiveFinalizationCommission: trAmountFraction( - params.poolParameters?.passiveFinalizationCommission - ), - passiveBakingCommission: trAmountFraction( - params.poolParameters?.passiveBakingCommission - ), - passiveTransactionCommission: trAmountFraction( - params.poolParameters?.passiveTransactionCommission - ), - finalizationCommissionRange: translateCommissionRange( - params.poolParameters?.commissionBounds?.finalization - ), - bakingCommissionRange: translateCommissionRange( - params.poolParameters?.commissionBounds?.baking - ), - transactionCommissionRange: translateCommissionRange( - params.poolParameters?.commissionBounds?.transaction - ), - minimumEquityCapital: unwrap( - params.poolParameters?.minimumEquityCapital?.value - ), - capitalBound: trAmountFraction( - params.poolParameters?.capitalBound?.value - ), - leverageBound: unwrap(params.poolParameters?.leverageBound?.value), - }, - gasRewards: { - baker: trAmountFraction(params.gasRewards?.baker), - accountCreation: trAmountFraction( - params.gasRewards?.accountCreation - ), - chainUpdate: trAmountFraction(params.gasRewards?.chainUpdate), - }, - mintDistribution: { - bakingReward: trAmountFraction( - params.mintDistribution?.bakingReward - ), - finalizationReward: trAmountFraction( - params.mintDistribution?.finalizationReward - ), - }, - consensusParameters: { - timeoutParameters: { - timeoutBase: unwrap( - params.consensusParameters?.timeoutParameters?.timeoutBase - ?.value + rewardPeriodLength: unwrap( + params.timeParameters?.rewardPeriodLength?.value?.value + ), + mintPerPayday: trMintRate(params.timeParameters?.mintPerPayday), + delegatorCooldown: unwrap( + params.cooldownParameters?.delegatorCooldown?.value + ), + poolOwnerCooldown: unwrap( + params.cooldownParameters?.poolOwnerCooldown?.value + ), + passiveFinalizationCommission: trAmountFraction( + params.poolParameters?.passiveFinalizationCommission + ), + passiveBakingCommission: trAmountFraction( + params.poolParameters?.passiveBakingCommission + ), + passiveTransactionCommission: trAmountFraction( + params.poolParameters?.passiveTransactionCommission + ), + finalizationCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.finalization + ), + bakingCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.baking + ), + transactionCommissionRange: translateCommissionRange( + params.poolParameters?.commissionBounds?.transaction + ), + minimumEquityCapital: unwrap( + params.poolParameters?.minimumEquityCapital?.value + ), + capitalBound: trAmountFraction( + params.poolParameters?.capitalBound?.value + ), + leverageBound: unwrap(params.poolParameters?.leverageBound?.value), + rewardParameters: { + ...commonRewardParameters, + gASRewards: { + baker: trAmountFraction(params.gasRewards?.baker), + accountCreation: trAmountFraction( + params.gasRewards?.accountCreation ), - timeoutDecrease: unwrap( - params.consensusParameters?.timeoutParameters - ?.timeoutDecrease + chainUpdate: trAmountFraction(params.gasRewards?.chainUpdate), + }, + mintDistribution: { + bakingReward: trAmountFraction( + params.mintDistribution?.bakingReward ), - timeoutIncrease: unwrap( - params.consensusParameters?.timeoutParameters - ?.timeoutIncrease + finalizationReward: trAmountFraction( + params.mintDistribution?.finalizationReward ), }, - minBlockTime: unwrap( - params.consensusParameters?.minBlockTime?.value - ), - blockEnergyLimit: unwrap( - params.consensusParameters?.blockEnergyLimit?.value - ), - }, - finalizationCommiteeParameters: { - finalizerRelativeStakeThreshold: trAmountFraction( - params.finalizationCommitteeParameters - ?.finalizerRelativeStakeThreshold - ), - minimumFinalizers: unwrap( - params.finalizationCommitteeParameters?.minimumFinalizers - ), - maximumFinalizers: unwrap( - params.finalizationCommitteeParameters?.maximumFinalizers - ), }, + timeoutBase: unwrap( + params.consensusParameters?.timeoutParameters?.timeoutBase?.value + ), + timeoutDecrease: unwrap( + params.consensusParameters?.timeoutParameters?.timeoutDecrease + ), + timeoutIncrease: unwrap( + params.consensusParameters?.timeoutParameters?.timeoutIncrease + ), + minBlockTime: unwrap(params.consensusParameters?.minBlockTime?.value), + blockEnergyLimit: unwrap( + params.consensusParameters?.blockEnergyLimit?.value + ), + finalizerRelativeStakeThreshold: trAmountFraction( + params.finalizationCommitteeParameters + ?.finalizerRelativeStakeThreshold + ), + minimumFinalizers: unwrap( + params.finalizationCommitteeParameters?.minimumFinalizers + ), + maximumFinalizers: unwrap( + params.finalizationCommitteeParameters?.maximumFinalizers + ), }; } @@ -757,10 +744,12 @@ export function consensusInfo(ci: v2.ConsensusInfo): v1.ConsensusStatus { const ci1: v1.ConsensusStatusV1 = { ...common, - currentTimeoutDuration: unwrap(ci.currentTimeoutDuration?.value), - currentRound: unwrap(ci.currentRound?.value), - currentEpoch: unwrap(ci.currentEpoch?.value), - triggerBlockTime: trTimestamp(ci.triggerBlockTime), + concordiumBFTStatus: { + currentTimeoutDuration: unwrap(ci.currentTimeoutDuration?.value), + currentRound: unwrap(ci.currentRound?.value), + currentEpoch: unwrap(ci.currentEpoch?.value), + triggerBlockTime: trTimestamp(ci.triggerBlockTime), + }, }; return ci1; @@ -1276,9 +1265,9 @@ function trEuroPerEnergyUpdate( } function trMicroCcdPerEuroUpdate( exchangeRate: v2.ExchangeRate -): v1.MicroCCDPerEuroUpdate { +): v1.MicroGtuPerEuroUpdate { return { - updateType: v1.UpdateType.MicroCCDPerEuro, + updateType: v1.UpdateType.MicroGtuPerEuro, update: unwrap(exchangeRate.value), }; } @@ -1738,10 +1727,10 @@ function trAuthorizationsV0(auths: v2.AuthorizationsV0): v1.AuthorizationsV0 { addIdentityProvider: trAccessStructure(auths.addIdentityProvider), addAnonymityRevoker: trAccessStructure(auths.addAnonymityRevoker), emergency: trAccessStructure(auths.emergency), - consensus: trAccessStructure(auths.parameterConsensus), + electionDifficulty: trAccessStructure(auths.parameterConsensus), euroPerEnergy: trAccessStructure(auths.parameterEuroPerEnergy), foundationAccount: trAccessStructure(auths.parameterFoundationAccount), - microCCDPerEuro: trAccessStructure(auths.parameterMicroCCDPerEuro), + microGTUPerEuro: trAccessStructure(auths.parameterMicroCCDPerEuro), paramGASRewards: trAccessStructure(auths.parameterGasRewards), mintDistribution: trAccessStructure(auths.parameterMintDistribution), transactionFeeDistribution: trAccessStructure( diff --git a/packages/common/src/JsonRpcClient.ts b/packages/common/src/JsonRpcClient.ts index 0323911cf..5d6bdbe24 100644 --- a/packages/common/src/JsonRpcClient.ts +++ b/packages/common/src/JsonRpcClient.ts @@ -4,6 +4,7 @@ import { AccountTransaction, AccountTransactionSignature, buildInvoker, + ConcordiumBftStatus, ConsensusStatus, ConsensusStatusV0, ConsensusStatusV1, @@ -137,14 +138,17 @@ export class JsonRpcClient { type CS = ConsensusStatusV0 & ConsensusStatusV1; // TODO Avoid code duplication with nodejs client - const datePropertyKeys: (keyof CS)[] = [ + const datePropertyKeys: (keyof CS | keyof ConcordiumBftStatus)[] = [ 'blockLastReceivedTime', 'blockLastArrivedTime', 'genesisTime', 'currentEraGenesisTime', 'lastFinalizedTime', + + // v1 + 'triggerBlockTime', ]; - const bigIntPropertyKeys: (keyof CS)[] = [ + const bigIntPropertyKeys: (keyof CS | keyof ConcordiumBftStatus)[] = [ 'epochDuration', 'slotDuration', 'bestBlockHeight', @@ -153,10 +157,11 @@ export class JsonRpcClient { 'blocksVerifiedCount', 'blocksReceivedCount', 'protocolVersion', + + // v1 'currentTimeoutDuration', 'currentRound', 'currentEpoch', - 'triggerBlockTime', ]; const res = transformJsonResponse( diff --git a/packages/common/src/blockSummaryHelpers.ts b/packages/common/src/blockSummaryHelpers.ts index 3dc8fce06..ebebe3e3c 100644 --- a/packages/common/src/blockSummaryHelpers.ts +++ b/packages/common/src/blockSummaryHelpers.ts @@ -23,7 +23,7 @@ export const isUpdateQueuesV1 = (uq: UpdateQueues): uq is UpdateQueuesV1 => /** Whether {@link UpdateQueues} parameter given is of type {@link UpdateQueuesV2} */ export const isUpdateQueuesV2 = (uq: UpdateQueues): uq is UpdateQueuesV2 => - (uq as UpdateQueuesV2).timeoutParameters !== undefined; + (uq as UpdateQueuesV2).consensus2TimingParameters !== undefined; export const isUpdatesV0 = (u: Updates): u is UpdatesV0 => isUpdateQueuesV0(u.updateQueues); @@ -38,7 +38,9 @@ export const isBlockSummaryV0 = (bs: BlockSummary): bs is BlockSummaryV0 => bs.protocolVersion === undefined || bs.protocolVersion <= 3n; export const isBlockSummaryV1 = (bs: BlockSummary): bs is BlockSummaryV1 => - bs.protocolVersion !== undefined && bs.protocolVersion > 3n; + bs.protocolVersion !== undefined && + bs.protocolVersion > 3n && + bs.protocolVersion <= 5n; export const isBlockSummaryV2 = (bs: BlockSummary): bs is BlockSummaryV2 => bs.protocolVersion !== undefined && bs.protocolVersion > 5n; diff --git a/packages/common/src/energyCost.ts b/packages/common/src/energyCost.ts index 4735c16d6..11b168678 100644 --- a/packages/common/src/energyCost.ts +++ b/packages/common/src/energyCost.ts @@ -64,13 +64,13 @@ export function getEnergyCost( */ export function getExchangeRate({ euroPerEnergy, - microCCDPerEuro, + microGTUPerEuro, }: ChainParameters): Ratio { const denominator = BigInt( - euroPerEnergy.denominator * microCCDPerEuro.denominator + euroPerEnergy.denominator * microGTUPerEuro.denominator ); const numerator = BigInt( - euroPerEnergy.numerator * microCCDPerEuro.numerator + euroPerEnergy.numerator * microGTUPerEuro.numerator ); return { numerator, denominator }; } diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 5ae3b0913..15d116c9c 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -322,7 +322,7 @@ export interface RewardParametersV0 extends RewardParametersCommon { /** The current mint distribution */ mintDistribution: MintDistributionV0; /** The current gas rewards parameters */ - gasRewards: GasRewardsV0; + gASRewards: GasRewardsV0; } /** Reward parameters used in protocol versions 4 and 5 ({@link ChainParametersV1}). */ @@ -330,7 +330,7 @@ export interface RewardParametersV1 extends RewardParametersCommon { /** The current mint distribution */ mintDistribution: MintDistributionV1; /** The current gas rewards parameters */ - gasRewards: GasRewardsV0; + gASRewards: GasRewardsV0; } /** Reward parameters used from protocol version 6 ({@link ChainParametersV2}). */ @@ -338,7 +338,7 @@ export interface RewardParametersV2 extends RewardParametersCommon { /** The current mint distribution */ mintDistribution: MintDistributionV1; /** The current gas rewards parameters */ - gasRewards: GasRewardsV1; + gASRewards: GasRewardsV1; } /** Cooldown parameters used from protocol version 1-3 */ @@ -413,8 +413,6 @@ export interface TimeoutParameters { /** Consensus parameters, used from protocol version 6 */ export interface ConsensusParameters { - /** Parameters controlling round timeouts. */ - timeoutParameters: TimeoutParameters; /** Minimum time interval between blocks. */ minBlockTime: Duration; /** Maximum energy allowed per block. */ @@ -442,60 +440,46 @@ export interface ChainParametersCommon { /** Rate of euros per energy */ euroPerEnergy: ExchangeRate; /** Rate of micro CCD per euro */ - microCCDPerEuro: ExchangeRate; + microGTUPerEuro: ExchangeRate; /** Limit for the number of account creations in a block */ accountCreationLimit: number; /** The chain foundation account */ foundationAccount: Base58String; + /** The chain foundation account index */ + foundationAccountIndex?: bigint; } /** Chain parameters used from protocol version 1-3 */ export type ChainParametersV0 = ChainParametersCommon & CooldownParametersV0 & - PoolParametersV0 & - RewardParametersV0 & { + PoolParametersV0 & { /** The election difficulty for consensus lottery */ electionDifficulty: number; + /** The election difficulty for consensus lottery */ + rewardParameters: RewardParametersV0; }; /** Chain parameters used in protocol versions 4 and 5 */ export type ChainParametersV1 = ChainParametersCommon & - RewardParametersV1 & { - /** - * The extra number of epochs before reduction in stake - * or baker deregistration is completed. - */ - cooldownParameters: CooldownParametersV1; - /** - * The time parameters, indicating the mint rate and - * the reward period length, i.e. the tiem between paydays - */ - timeParameters: TimeParametersV1; - /** Parameters governing baking pools and their commissions. */ - poolParameters: PoolParametersV1; + CooldownParametersV1 & + TimeParametersV1 & + PoolParametersV1 & { /** The election difficulty for consensus lottery */ electionDifficulty: number; + /** The election difficulty for consensus lottery */ + rewardParameters: RewardParametersV1; }; /** Chain parameters used from protocol version 6 */ export type ChainParametersV2 = ChainParametersCommon & - RewardParametersV2 & { - /** The consensus parameters. */ - consensusParameters: ConsensusParameters; - /** - * The extra number of epochs before reduction in stake - * or baker deregistration is completed. - */ - cooldownParameters: CooldownParametersV1; - /** - * The time parameters, indicating the mint rate and - * the reward period length, i.e. the tiem between paydays - */ - timeParameters: TimeParametersV1; - /** Parameters governing baking pools and their commissions. */ - poolParameters: PoolParametersV1; - /** The finalization committee parameters */ - finalizationCommiteeParameters: FinalizationCommitteeParameters; + CooldownParametersV1 & + TimeParametersV1 & + PoolParametersV1 & + FinalizationCommitteeParameters & + TimeoutParameters & + ConsensusParameters & { + /** The election difficulty for consensus lottery */ + rewardParameters: RewardParametersV2; }; /** Union of all chain parameters across all protocol versions */ @@ -511,7 +495,7 @@ export interface Authorization { interface AuthorizationsCommon { emergency: Authorization; - microCCDPerEuro: Authorization; + microGTUPerEuro: Authorization; euroPerEnergy: Authorization; transactionFeeDistribution: Authorization; foundationAccount: Authorization; @@ -522,7 +506,10 @@ interface AuthorizationsCommon { * For protocol version 3 and earlier, this controls the authorization of the bakerStakeThreshold update. */ poolParameters: Authorization; - consensus: Authorization; + /** + * For protocol version 6 and later, this controls the authorization of consensus related updates. + */ + electionDifficulty: Authorization; addAnonymityRevoker: Authorization; addIdentityProvider: Authorization; keys: VerifyKey[]; @@ -579,15 +566,14 @@ export interface UpdateQueueQueue { export interface UpdateQueue { nextSequenceNumber: bigint; - queue: UpdateQueueQueue; + queue: UpdateQueueQueue[]; } interface UpdateQueuesCommon { - microCCDPerEuro: UpdateQueue; + microGTUPerEuro: UpdateQueue; euroPerEnergy: UpdateQueue; transactionFeeDistribution: UpdateQueue; foundationAccount: UpdateQueue; - electionDifficulty: UpdateQueue; mintDistribution: UpdateQueue; protocol: UpdateQueue; gasRewards: UpdateQueue; @@ -602,6 +588,7 @@ interface UpdateQueuesCommon { * Used from protocol version 1-3 */ export interface UpdateQueuesV0 extends UpdateQueuesCommon { + electionDifficulty: UpdateQueue; bakerStakeThreshold: UpdateQueue; } @@ -609,6 +596,7 @@ export interface UpdateQueuesV0 extends UpdateQueuesCommon { * Used in protocol version 4 and 5 */ export interface UpdateQueuesV1 extends UpdateQueuesCommon { + electionDifficulty: UpdateQueue; cooldownParameters: UpdateQueue; timeParameters: UpdateQueue; poolParameters: UpdateQueue; @@ -618,10 +606,7 @@ export interface UpdateQueuesV1 extends UpdateQueuesCommon { * Used from protocol version 6 */ export interface UpdateQueuesV2 extends UpdateQueuesV1 { - timeoutParameters: UpdateQueue; - minBlockTime: UpdateQueue; - blockEnergyLimit: UpdateQueue; - finalizationCommiteeParameters: UpdateQueue; + consensus2TimingParameters: UpdateQueue; } export type UpdateQueues = UpdateQueuesV0 | UpdateQueuesV1 | UpdateQueuesV2; @@ -901,8 +886,7 @@ export interface ConsensusStatusV0 extends ConsensusStatusCommon { slotDuration: Duration; } -/** Consensus status used from protocol version 6 */ -export type ConsensusStatusV1 = ConsensusStatusCommon & { +export interface ConcordiumBftStatus { /** Current duration before a round times out, in milliseconds */ currentTimeoutDuration: Duration; /** Current round */ @@ -914,6 +898,11 @@ export type ConsensusStatusV1 = ConsensusStatusCommon & { * the trigger block for the epoch transition. */ triggerBlockTime: Date; +} + +/** Consensus status used from protocol version 6 */ +export type ConsensusStatusV1 = ConsensusStatusCommon & { + concordiumBFTStatus: ConcordiumBftStatus; }; /** Union of consensus status types used across all protocol versions */ diff --git a/packages/common/src/types/chainUpdate.ts b/packages/common/src/types/chainUpdate.ts index 61a1bd05e..5d66fe12a 100644 --- a/packages/common/src/types/chainUpdate.ts +++ b/packages/common/src/types/chainUpdate.ts @@ -54,8 +54,8 @@ export type EuroPerEnergyUpdate = ChainUpdate< >; /** An update to the micro CCD per euro exchange rate */ -export type MicroCCDPerEuroUpdate = ChainUpdate< - UpdateType.MicroCCDPerEuro, +export type MicroGtuPerEuroUpdate = ChainUpdate< + UpdateType.MicroGtuPerEuro, ExchangeRate >; @@ -160,7 +160,7 @@ export type PendingAuthorizationKeysUpdate = ChainUpdate< /** A union of chain updates, barring key updates */ export type CommonUpdate = - | MicroCCDPerEuroUpdate + | MicroGtuPerEuroUpdate | EuroPerEnergyUpdate | TransactionFeeDistributionUpdate | FoundationAccountUpdate @@ -198,7 +198,7 @@ export enum UpdateType { Protocol = 'protocol', ElectionDifficulty = 'electionDifficulty', EuroPerEnergy = 'euroPerEnergy', - MicroCCDPerEuro = 'microCCDPerEuro', + MicroGtuPerEuro = 'microGtuPerEuro', FoundationAccount = 'foundationAccount', MintDistribution = 'mintDistribution', TransactionFeeDistribution = 'transactionFeeDistribution', diff --git a/packages/common/src/versionedTypeHelpers.ts b/packages/common/src/versionedTypeHelpers.ts index fe9fcac30..e05a3b868 100644 --- a/packages/common/src/versionedTypeHelpers.ts +++ b/packages/common/src/versionedTypeHelpers.ts @@ -61,14 +61,14 @@ export const isChainParametersV0 = ( export const isChainParametersV1 = ( cp: ChainParameters ): cp is ChainParametersV1 => - (cp as ChainParametersV1).timeParameters !== undefined && + (cp as ChainParametersV1).mintPerPayday !== undefined && !isChainParametersV2(cp); /** Whether {@link ChainParameters} parameter given is of type {@link ChainParametersV2} */ export const isChainParametersV2 = ( cp: ChainParameters ): cp is ChainParametersV2 => - (cp as ChainParametersV2).consensusParameters !== undefined; + (cp as ChainParametersV2).maximumFinalizers !== undefined; /** Whether {@link Keys} parameter given is of type {@link KeysV0} */ export const isKeysV0 = (ks: Keys): ks is KeysV0 => @@ -89,14 +89,13 @@ export const isBlockInfoV1 = (bi: BlockInfo): bi is BlockInfoV1 => /** Whether {@link ConensusStatus} parameter given is of type {@link ConsensusStatusV0} */ export const isConsensusStatusV0 = ( cs: ConsensusStatus -): cs is ConsensusStatusV0 => - (cs as ConsensusStatusV0).slotDuration !== undefined; +): cs is ConsensusStatusV0 => (cs as ConsensusStatusV0).slotDuration != null; /** Whether {@link ConensusStatus} parameter given is of type {@link ConsensusStatusV1} */ export const isConsensusStatusV1 = ( cs: ConsensusStatus ): cs is ConsensusStatusV1 => - (cs as ConsensusStatusV1).currentRound !== undefined; + (cs as ConsensusStatusV1).concordiumBFTStatus !== undefined; /** Whether {@link ElectionInfo} parameter given is of type {@link ElectionInfoV0} */ export const isElectionInfoV0 = (ei: ElectionInfo): ei is ElectionInfoV0 => diff --git a/packages/nodejs/src/client.ts b/packages/nodejs/src/client.ts index 26fd0886e..a814c5c5c 100644 --- a/packages/nodejs/src/client.ts +++ b/packages/nodejs/src/client.ts @@ -80,6 +80,7 @@ import { ConsensusParameters, TimeoutParameters, Ratio, + ConcordiumBftStatus, } from '@concordium/common-sdk'; import { buildJsonResponseReviver, @@ -390,6 +391,7 @@ export default class ConcordiumNodeClient { 'index', 'subindex', 'protocolVersion', + 'foundationAccountIndex', // v0 keys 'bakerCooldownEpochs', @@ -491,14 +493,17 @@ export default class ConcordiumNodeClient { new Empty() ); - const datePropertyKeys: (keyof CS)[] = [ + const datePropertyKeys: (keyof CS | keyof ConcordiumBftStatus)[] = [ 'blockLastReceivedTime', 'blockLastArrivedTime', 'genesisTime', 'currentEraGenesisTime', 'lastFinalizedTime', + + //v1 + 'triggerBlockTime', ]; - const bigIntPropertyKeys: (keyof CS)[] = [ + const bigIntPropertyKeys: (keyof CS | keyof ConcordiumBftStatus)[] = [ 'epochDuration', 'slotDuration', 'bestBlockHeight', @@ -507,10 +512,11 @@ export default class ConcordiumNodeClient { 'blocksVerifiedCount', 'blocksReceivedCount', 'protocolVersion', + + // v1 'currentTimeoutDuration', 'currentRound', 'currentEpoch', - 'triggerBlockTime', ]; const consensusStatus = unwrapJsonResponse( diff --git a/packages/nodejs/test/CIS2Contract.test.ts b/packages/nodejs/test/CIS2Contract.test.ts index a18a86340..b13886fec 100644 --- a/packages/nodejs/test/CIS2Contract.test.ts +++ b/packages/nodejs/test/CIS2Contract.test.ts @@ -6,7 +6,7 @@ import { serializeTypeValue, TransactionEventTag, } from '@concordium/common-sdk'; -import { getNodeClient } from './testHelpers'; +import { getNodeClientV2 as getNodeClient } from './testHelpers'; const CIS2_FT_ADDRESS: ContractAddress = { index: 3496n, diff --git a/packages/nodejs/test/cis0.test.ts b/packages/nodejs/test/cis0.test.ts index 83208ff6c..62df41afa 100644 --- a/packages/nodejs/test/cis0.test.ts +++ b/packages/nodejs/test/cis0.test.ts @@ -1,5 +1,5 @@ import { CIS0, cis0Supports } from '@concordium/common-sdk'; -import { getNodeClient } from './testHelpers'; +import { getNodeClientV2 as getNodeClient } from './testHelpers'; const client = getNodeClient(); diff --git a/packages/nodejs/test/client.test.ts b/packages/nodejs/test/client.test.ts new file mode 100644 index 000000000..5e0007df2 --- /dev/null +++ b/packages/nodejs/test/client.test.ts @@ -0,0 +1,291 @@ +import { + isBlockSummaryV0, + isBlockSummaryV1, + isBlockSummaryV2, + isConsensusStatusV0, + isConsensusStatusV1, +} from '@concordium/common-sdk'; +import { getNodeClient } from './testHelpers'; + +/** + * These tests mostly serve the purpose of making sure that the types exposed follow the format returned by the API, + * i.e. we don't change the types to conform to the v2 API, but rather translate the v2 types to the v1 types until we can + * remove the v1 API entirely. + */ + +const address = '127.0.0.1'; +const port = 10000; + +const client = getNodeClient(address, port); + +// eslint-disable-next-line prefer-const +let CHAIN_GENESIS_BLOCK: string | undefined = undefined; +// eslint-disable-next-line prefer-const +let PV1_BLOCK: string | undefined = undefined; +// eslint-disable-next-line prefer-const +let PV4_BLOCK: string | undefined = undefined; +// eslint-disable-next-line prefer-const +let PV6_BLOCK: string | undefined = undefined; + +// Stagenet blocks. +// PV4_BLOCK = 'f97d975f0e92297c51e24c3b0d8fd39dfe8e1b148d993eba6e9389d4083f7a64'; +// PV6_BLOCK = 'a3e46b2cf01d611c7507a2c2a3597da681f7b7b503b7a1f1372e661e040790f3'; + +// Mainnet blocks. +CHAIN_GENESIS_BLOCK = + '9dd9ca4d19e9393877d2c44b70f89acbfc0883c2243e5eeaecc0d1cd0503f478'; +PV4_BLOCK = '568589c9f5b3a3989c24d4c916bc2417a64c6dff6ec987595349c551a829d332'; + +test.each([CHAIN_GENESIS_BLOCK, PV1_BLOCK, PV4_BLOCK, PV6_BLOCK])( + 'blockSummary format as expected', + async (block) => { + if (block === undefined) { + return; + } + + const bs = await client.getBlockSummary(block); + + if (!bs) { + throw new Error('could not find block'); + } + + console.log(bs.protocolVersion); + + // BlockSummary + expect(typeof bs.protocolVersion).toEqual('bigint'); + + // UpdateQueues + expect( + typeof bs.updates.updateQueues.foundationAccount.nextSequenceNumber + ).toEqual('bigint'); + expect( + Array.isArray(bs.updates.updateQueues.foundationAccount.queue) + ).toBeTruthy(); + expect( + typeof bs.updates.updateQueues.euroPerEnergy.nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.mintDistribution.nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.microGTUPerEuro.nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.protocol.nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.rootKeys.nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.gasRewards.nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.level1Keys.nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.level2Keys.nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.addAnonymityRevoker + .nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.addIdentityProvider + .nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.transactionFeeDistribution + .nextSequenceNumber + ).toEqual('bigint'); + + // Keys + expect(bs.updates.keys.rootKeys.keys).toBeDefined(); + expect(bs.updates.keys.rootKeys.threshold).toBeDefined(); + expect(bs.updates.keys.level1Keys.keys).toBeDefined(); + expect(bs.updates.keys.level2Keys.keys).toBeDefined(); + expect( + bs.updates.keys.level2Keys.addAnonymityRevoker.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.poolParameters.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.transactionFeeDistribution.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.addIdentityProvider.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.protocol.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.microGTUPerEuro.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.mintDistribution.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.euroPerEnergy.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.foundationAccount.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.electionDifficulty.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.emergency.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.paramGASRewards.authorizedKeys + ).toBeDefined(); + + // Test format of chain parameters holds + expect( + typeof bs.updates.chainParameters.microGTUPerEuro.numerator + ).toEqual('bigint'); + expect( + typeof bs.updates.chainParameters.microGTUPerEuro.denominator + ).toEqual('bigint'); + expect( + bs.updates.chainParameters.rewardParameters.gASRewards.baker + ).toBeDefined(); + expect( + bs.updates.chainParameters.rewardParameters.gASRewards.chainUpdate + ).toBeDefined(); + expect( + bs.updates.chainParameters.rewardParameters.gASRewards + .accountCreation + ).toBeDefined(); + expect( + bs.updates.chainParameters.rewardParameters.mintDistribution + .bakingReward + ).toBeDefined(); + expect( + bs.updates.chainParameters.rewardParameters.mintDistribution + .finalizationReward + ).toBeDefined(); + expect(bs.updates.chainParameters.euroPerEnergy).toBeDefined(); + // expect(bs.updates.chainParameters.foundationAccountIndex).toBeDefined(); + expect(bs.updates.chainParameters.accountCreationLimit).toBeDefined(); + + if (isBlockSummaryV0(bs)) { + expect( + typeof bs.updates.updateQueues.electionDifficulty + .nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.bakerStakeThreshold + .nextSequenceNumber + ).toEqual('bigint'); + + expect( + typeof bs.updates.chainParameters.bakerCooldownEpochs + ).toEqual('bigint'); + } else if (isBlockSummaryV1(bs)) { + expect( + typeof bs.updates.updateQueues.electionDifficulty + .nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.poolParameters.nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.timeParameters.nextSequenceNumber + ).toEqual('bigint'); + expect( + typeof bs.updates.updateQueues.cooldownParameters + .nextSequenceNumber + ).toEqual('bigint'); + + expect( + bs.updates.keys.level2Keys.cooldownParameters.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.timeParameters.authorizedKeys + ).toBeDefined(); + + expect(bs.updates.chainParameters.electionDifficulty).toBeDefined(); + expect( + bs.updates.chainParameters.rewardParameters.gASRewards + .finalizationProof + ); + expect(bs.updates.chainParameters.mintPerPayday).toBeDefined(); + expect(bs.updates.chainParameters.capitalBound).toBeDefined(); + expect(bs.updates.chainParameters.leverageBound).toBeDefined(); + expect( + bs.updates.chainParameters.finalizationCommissionRange.min + ).toBeDefined(); + } else if (isBlockSummaryV2(bs)) { + expect( + typeof bs.updates.updateQueues.consensus2TimingParameters + .nextSequenceNumber + ).toEqual('bigint'); + + expect( + bs.updates.keys.level2Keys.cooldownParameters.authorizedKeys + ).toBeDefined(); + expect( + bs.updates.keys.level2Keys.timeParameters.authorizedKeys + ).toBeDefined(); + + expect(bs.updates.chainParameters.minimumFinalizers).toBeDefined(); + expect(bs.updates.chainParameters.maximumFinalizers).toBeDefined(); + expect(typeof bs.updates.chainParameters.blockEnergyLimit).toEqual( + 'bigint' + ); + expect(typeof bs.updates.chainParameters.minBlockTime).toEqual( + 'bigint' + ); + expect(typeof bs.updates.chainParameters.timeoutBase).toEqual( + 'bigint' + ); + expect( + typeof bs.updates.chainParameters.timeoutDecrease.numerator + ).toEqual('bigint'); + expect( + typeof bs.updates.chainParameters.timeoutIncrease.denominator + ).toEqual('bigint'); + expect( + bs.updates.chainParameters.finalizerRelativeStakeThreshold + ).toBeDefined(); + } + } +); + +test('consensusStatus format as expected', async () => { + const cs = await client.getConsensusStatus(); + + expect(typeof cs.protocolVersion).toEqual('bigint'); + expect(cs.bestBlock).toBeDefined(); + expect(cs.genesisTime instanceof Date).toBeTruthy(); + expect(cs.genesisBlock).toBeDefined(); + expect(cs.genesisIndex).toBeDefined(); + expect(typeof cs.epochDuration).toEqual('bigint'); + expect(typeof cs.bestBlockHeight).toEqual('bigint'); + expect(typeof cs.finalizationCount).toEqual('bigint'); + expect(cs.lastFinalizedBlock).toBeDefined(); + expect(typeof cs.blocksReceivedCount).toEqual('bigint'); + expect(typeof cs.blocksVerifiedCount).toEqual('bigint'); + expect(cs.blockArriveLatencyEMA).toBeDefined(); + expect(cs.blockLastArrivedTime instanceof Date).toBeTruthy(); + expect(cs.currentEraGenesisTime instanceof Date).toBeTruthy(); + expect(cs.blockArriveLatencyEMSD).toBeDefined(); + expect(cs.currentEraGenesisBlock).toBeDefined(); + expect(cs.transactionsPerBlockEMA).toBeDefined(); + expect(typeof cs.lastFinalizedBlockHeight).toEqual('bigint'); + expect(cs.transactionsPerBlockEMSD).toBeDefined(); + + if (isConsensusStatusV0(cs)) { + expect(typeof cs.slotDuration).toEqual('bigint'); + } else if (isConsensusStatusV1(cs)) { + expect(typeof cs.concordiumBFTStatus.currentTimeoutDuration).toEqual( + 'bigint' + ); + expect(typeof cs.concordiumBFTStatus.currentEpoch).toEqual('bigint'); + expect(typeof cs.concordiumBFTStatus.currentRound).toEqual('bigint'); + expect( + cs.concordiumBFTStatus.triggerBlockTime instanceof Date + ).toBeTruthy(); + } +}); diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index 569fc7580..1e6775963 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -20,7 +20,7 @@ import { import { getModuleBuffer, getIdentityInput, - getNodeClient, + getNodeClientV2, getNodeClientWeb, } from './testHelpers'; import * as ed from '@noble/ed25519'; @@ -36,7 +36,7 @@ global.TextEncoder = TextEncoder as any; global.TextDecoder = TextDecoder as any; /* eslint-enable @typescript-eslint/no-explicit-any */ -const clientV2 = getNodeClient(); +const clientV2 = getNodeClientV2(); const clientWeb = getNodeClientWeb(); const testAccount = new v1.AccountAddress( diff --git a/packages/nodejs/test/events.test.ts b/packages/nodejs/test/events.test.ts index 4b4d9aecf..00f57bedd 100644 --- a/packages/nodejs/test/events.test.ts +++ b/packages/nodejs/test/events.test.ts @@ -1,6 +1,6 @@ import * as expected from './resources/expectedJsons'; import { streamToList } from '@concordium/common-sdk'; -import { getNodeClient } from './testHelpers'; +import { getNodeClientV2 as getNodeClient } from './testHelpers'; const client = getNodeClient(); diff --git a/packages/nodejs/test/getConsensusStatus.test.ts b/packages/nodejs/test/getConsensusStatus.test.ts index 241279cd0..ff9c5d8af 100644 --- a/packages/nodejs/test/getConsensusStatus.test.ts +++ b/packages/nodejs/test/getConsensusStatus.test.ts @@ -1,5 +1,5 @@ import { ConsensusStatus, isHex } from '@concordium/common-sdk'; -import { getNodeClient } from './testHelpers'; +import { getNodeClientV2 as getNodeClient } from './testHelpers'; const client = getNodeClient(); test('retrieves the consensus status from the node with correct types', async () => { diff --git a/packages/nodejs/test/manualTests.test.ts b/packages/nodejs/test/manualTests.test.ts index 5de22b882..cb2295935 100644 --- a/packages/nodejs/test/manualTests.test.ts +++ b/packages/nodejs/test/manualTests.test.ts @@ -4,7 +4,7 @@ import { buildBasicAccountSigner, signTransaction, } from '@concordium/common-sdk'; -import { getNodeClient } from '../test/testHelpers'; +import { getNodeClientV2 as getNodeClient } from '../test/testHelpers'; const client = getNodeClient(); diff --git a/packages/nodejs/test/rejectReasons.test.ts b/packages/nodejs/test/rejectReasons.test.ts index e0f8b9f48..c6158f344 100644 --- a/packages/nodejs/test/rejectReasons.test.ts +++ b/packages/nodejs/test/rejectReasons.test.ts @@ -1,6 +1,6 @@ import * as expected from './resources/expectedJsons'; import { streamToList } from '@concordium/common-sdk'; -import { getNodeClient } from './testHelpers'; +import { getNodeClientV2 as getNodeClient } from './testHelpers'; const client = getNodeClient(); diff --git a/packages/nodejs/test/resources/expectedJsons.ts b/packages/nodejs/test/resources/expectedJsons.ts index 68699978b..00a622673 100644 --- a/packages/nodejs/test/resources/expectedJsons.ts +++ b/packages/nodejs/test/resources/expectedJsons.ts @@ -149,7 +149,7 @@ export const blockItemStatusUpdate = { type: 'updateTransaction', effectiveTime: 0n, payload: { - updateType: 'microCCDPerEuro', + updateType: 'microGtuPerEuro', update: { numerator: 17592435270983729152n, denominator: 163844642115n, @@ -459,7 +459,7 @@ export const transactionEventList = [ hash: '49d7b5c3234dc17bd904af0b63712dc0a6680b96ad556c5ac1103d8cdd128891', effectiveTime: 0n, payload: { - updateType: 'microCCDPerEuro', + updateType: 'microGtuPerEuro', update: { denominator: 126230907181n, numerator: 9397474320418127872n, @@ -1613,60 +1613,58 @@ export const regularAccountInfo = { export const chainParameters: ChainParametersV1 = { electionDifficulty: 0.025, euroPerEnergy: { numerator: 1n, denominator: 50000n }, - microCCDPerEuro: { + microGTUPerEuro: { numerator: 697170112016908288n, denominator: 7989497115n, }, accountCreationLimit: 10, foundationAccount: '3kBx2h5Y2veb4hZgAJWPrr8RyQESKm5TjzF3ti1QQ4VSYLwK1G', - timeParameters: { - mintPerPayday: 0.000261157877, - rewardPeriodLength: 24n, - }, - cooldownParameters: { - delegatorCooldown: 1209600n, - poolOwnerCooldown: 1814400n, - }, - poolParameters: { - passiveFinalizationCommission: 1, - passiveBakingCommission: 0.12, - passiveTransactionCommission: 0.12, - finalizationCommissionRange: { min: 1, max: 1 }, - bakingCommissionRange: { min: 0.1, max: 0.1 }, - transactionCommissionRange: { min: 0.1, max: 0.1 }, - minimumEquityCapital: 14000000000n, - capitalBound: 0.1, - leverageBound: { numerator: 3n, denominator: 1n }, - }, - transactionFeeDistribution: { baker: 0.45, gasAccount: 0.45 }, - gasRewards: { - baker: 0.25, - finalizationProof: 0.005, - accountCreation: 0.02, - chainUpdate: 0.005, - }, - mintDistribution: { bakingReward: 0.6, finalizationReward: 0.3 }, + mintPerPayday: 0.000261157877, + rewardPeriodLength: 24n, + delegatorCooldown: 1209600n, + poolOwnerCooldown: 1814400n, + passiveFinalizationCommission: 1, + passiveBakingCommission: 0.12, + passiveTransactionCommission: 0.12, + finalizationCommissionRange: { min: 1, max: 1 }, + bakingCommissionRange: { min: 0.1, max: 0.1 }, + transactionCommissionRange: { min: 0.1, max: 0.1 }, + minimumEquityCapital: 14000000000n, + capitalBound: 0.1, + leverageBound: { numerator: 3n, denominator: 1n }, + rewardParameters: { + transactionFeeDistribution: { baker: 0.45, gasAccount: 0.45 }, + gASRewards: { + baker: 0.25, + finalizationProof: 0.005, + accountCreation: 0.02, + chainUpdate: 0.005, + }, + mintDistribution: { bakingReward: 0.6, finalizationReward: 0.3 }, + }, }; export const oldChainParameters: ChainParametersV0 = { electionDifficulty: 0.025, euroPerEnergy: { numerator: 1n, denominator: 50000n }, - microCCDPerEuro: { numerator: 50000000n, denominator: 1n }, + microGTUPerEuro: { numerator: 50000000n, denominator: 1n }, accountCreationLimit: 10, foundationAccount: '3kBx2h5Y2veb4hZgAJWPrr8RyQESKm5TjzF3ti1QQ4VSYLwK1G', bakerCooldownEpochs: 166n, minimumThresholdForBaking: 15000000000n, - transactionFeeDistribution: { baker: 0.45, gasAccount: 0.45 }, - gasRewards: { - baker: 0.25, - finalizationProof: 0.005, - accountCreation: 0.02, - chainUpdate: 0.005, - }, - mintDistribution: { - bakingReward: 0.6, - finalizationReward: 0.3, - mintPerSlot: 7.555665e-10, + rewardParameters: { + transactionFeeDistribution: { baker: 0.45, gasAccount: 0.45 }, + gASRewards: { + baker: 0.25, + finalizationProof: 0.005, + accountCreation: 0.02, + chainUpdate: 0.005, + }, + mintDistribution: { + bakingReward: 0.6, + finalizationReward: 0.3, + mintPerSlot: 7.555665e-10, + }, }, }; diff --git a/packages/nodejs/test/specialEvents.test.ts b/packages/nodejs/test/specialEvents.test.ts index 9e8584891..206580aa7 100644 --- a/packages/nodejs/test/specialEvents.test.ts +++ b/packages/nodejs/test/specialEvents.test.ts @@ -1,6 +1,6 @@ import * as expected from './resources/expectedJsons'; import { streamToList } from '@concordium/common-sdk'; -import { getNodeClient } from './testHelpers'; +import { getNodeClientV2 as getNodeClient } from './testHelpers'; const client = getNodeClient(); diff --git a/packages/nodejs/test/testHelpers.ts b/packages/nodejs/test/testHelpers.ts index 32cd47aba..dd498ce8d 100644 --- a/packages/nodejs/test/testHelpers.ts +++ b/packages/nodejs/test/testHelpers.ts @@ -1,10 +1,11 @@ /* eslint-disable import/no-extraneous-dependencies */ import * as fs from 'fs'; -import { credentials } from '@grpc/grpc-js/'; +import { credentials, Metadata } from '@grpc/grpc-js/'; import { ConcordiumGRPCClient, IdentityInput } from '@concordium/common-sdk'; import { decryptMobileWalletExport, EncryptedData } from '../src/wallet/crypto'; import { MobileWalletExport } from '../src/wallet/types'; import { createConcordiumClient } from '../src/clientV2'; +import ConcordiumNodeClient from '../src/client'; import ConcordiumNodeClientV2 from '@concordium/common-sdk/lib/GRPCClient'; import { GrpcWebFetchTransport } from '@protobuf-ts/grpcweb-transport'; @@ -14,10 +15,29 @@ import 'isomorphic-fetch'; export { getModuleBuffer } from '../src/util'; /** - * Creates a client to communicate with a local concordium-node + * Creates a gRPC v1 client (for nodeJS) to communicate with a local concordium-node * used for automatic tests. */ export function getNodeClient( + address = '127.0.0.1', + port = 10000 +): ConcordiumNodeClient { + const metadata = new Metadata(); + metadata.add('authentication', 'rpcadmin'); + return new ConcordiumNodeClient( + address, + port, + credentials.createInsecure(), + metadata, + 15000 + ); +} + +/** + * Creates a gRPC v2 client (for nodeJS) to communicate with a local concordium-node + * used for automatic tests. + */ +export function getNodeClientV2( address = 'node.testnet.concordium.com', port = 20000 ): ConcordiumNodeClientV2 { @@ -25,7 +45,12 @@ export function getNodeClient( timeout: 15000, }); } + // TODO find nice way to move this to web/common +/** + * Creates a gRPC v2 client (for web) to communicate with a local concordium-node + * used for automatic tests. + */ export function getNodeClientWeb( address = 'http://node.testnet.concordium.com', port = 20000 From 667b51022abcaf19e54c769f937aa1333afd5e9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Mon, 26 Jun 2023 13:27:36 +0200 Subject: [PATCH 38/41] Fix example --- examples/client/getBlockChainParameters.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/client/getBlockChainParameters.ts b/examples/client/getBlockChainParameters.ts index c87cd1e71..8eb666eab 100644 --- a/examples/client/getBlockChainParameters.ts +++ b/examples/client/getBlockChainParameters.ts @@ -60,7 +60,7 @@ const client = createConcordiumClient( // Check version of chain parameters if (isChainParametersV2(cp)) { - console.log('Minimum block time', cp.consensusParameters.minBlockTime); + console.log('Minimum block time', cp.minBlockTime); } else if (isChainParametersV1(cp)) { console.log('Minimum equity capital:', cp.minimumEquityCapital); } else { From 78fd776b0a9b860391f59a1347e2697054556fdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Mon, 26 Jun 2023 13:34:18 +0200 Subject: [PATCH 39/41] Fix markdown lint error --- packages/web/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web/README.md b/packages/web/README.md index b0c593143..9bd324b00 100644 --- a/packages/web/README.md +++ b/packages/web/README.md @@ -30,6 +30,7 @@ for more information ## ConcordiumGRPCClient + The SDK provides a gRPC client, which can interact with the [Concordium Node](https://github.com/Concordium/concordium-node) using gRPC-web. From a46df055f68d63d47d5028eb0c2b34bed10d5c87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Tue, 27 Jun 2023 12:52:19 +0200 Subject: [PATCH 40/41] Clean up stagenet test --- packages/nodejs/test/client.test.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/nodejs/test/client.test.ts b/packages/nodejs/test/client.test.ts index 4f793ecc3..bc45077a6 100644 --- a/packages/nodejs/test/client.test.ts +++ b/packages/nodejs/test/client.test.ts @@ -13,7 +13,7 @@ import { getNodeClient } from './testHelpers'; * remove the v1 API entirely. */ -const address = '127.0.0.1'; +const address = 'concordiumwalletnode.com'; const port = 10000; const client = getNodeClient(address, port); @@ -21,22 +21,16 @@ const client = getNodeClient(address, port); // eslint-disable-next-line prefer-const let CHAIN_GENESIS_BLOCK: string | undefined = undefined; // eslint-disable-next-line prefer-const -let PV1_BLOCK: string | undefined = undefined; -// eslint-disable-next-line prefer-const let PV4_BLOCK: string | undefined = undefined; // eslint-disable-next-line prefer-const let PV6_BLOCK: string | undefined = undefined; -// Stagenet blocks. -// PV4_BLOCK = 'f97d975f0e92297c51e24c3b0d8fd39dfe8e1b148d993eba6e9389d4083f7a64'; -// PV6_BLOCK = 'a3e46b2cf01d611c7507a2c2a3597da681f7b7b503b7a1f1372e661e040790f3'; - // Mainnet blocks. CHAIN_GENESIS_BLOCK = '9dd9ca4d19e9393877d2c44b70f89acbfc0883c2243e5eeaecc0d1cd0503f478'; PV4_BLOCK = '568589c9f5b3a3989c24d4c916bc2417a64c6dff6ec987595349c551a829d332'; -test.each([CHAIN_GENESIS_BLOCK, PV1_BLOCK, PV4_BLOCK, PV6_BLOCK])( +test.each([CHAIN_GENESIS_BLOCK, PV4_BLOCK, PV6_BLOCK])( 'blockSummary format as expected', async (block) => { if (block === undefined) { @@ -164,7 +158,7 @@ test.each([CHAIN_GENESIS_BLOCK, PV1_BLOCK, PV4_BLOCK, PV6_BLOCK])( .finalizationReward ).toBeDefined(); expect(bs.updates.chainParameters.euroPerEnergy).toBeDefined(); - // expect(bs.updates.chainParameters.foundationAccountIndex).toBeDefined(); + expect(bs.updates.chainParameters.foundationAccountIndex).toBeDefined(); expect(bs.updates.chainParameters.accountCreationLimit).toBeDefined(); if (isBlockSummaryV0(bs)) { From 480661b807c356fb0cefed61b747001c53acdc12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Tue, 27 Jun 2023 13:09:23 +0200 Subject: [PATCH 41/41] testnet tests --- packages/nodejs/test/client.test.ts | 15 ++++++--------- packages/nodejs/test/testHelpers.ts | 14 +++++++++----- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/packages/nodejs/test/client.test.ts b/packages/nodejs/test/client.test.ts index bc45077a6..81653e540 100644 --- a/packages/nodejs/test/client.test.ts +++ b/packages/nodejs/test/client.test.ts @@ -13,24 +13,21 @@ import { getNodeClient } from './testHelpers'; * remove the v1 API entirely. */ -const address = 'concordiumwalletnode.com'; -const port = 10000; - -const client = getNodeClient(address, port); +const client = getNodeClient(); // eslint-disable-next-line prefer-const let CHAIN_GENESIS_BLOCK: string | undefined = undefined; // eslint-disable-next-line prefer-const -let PV4_BLOCK: string | undefined = undefined; +let PV5_BLOCK: string | undefined = undefined; // eslint-disable-next-line prefer-const let PV6_BLOCK: string | undefined = undefined; -// Mainnet blocks. +// Testnet blocks. CHAIN_GENESIS_BLOCK = - '9dd9ca4d19e9393877d2c44b70f89acbfc0883c2243e5eeaecc0d1cd0503f478'; -PV4_BLOCK = '568589c9f5b3a3989c24d4c916bc2417a64c6dff6ec987595349c551a829d332'; + '4221332d34e1694168c2a0c0b3fd0f273809612cb13d000d5c2e00e85f50f796'; +PV5_BLOCK = '58daebb41ca195442593e10c1a67279bb839a8195c8ea7442ea7116d87114fbb'; -test.each([CHAIN_GENESIS_BLOCK, PV4_BLOCK, PV6_BLOCK])( +test.each([CHAIN_GENESIS_BLOCK, PV5_BLOCK, PV6_BLOCK])( 'blockSummary format as expected', async (block) => { if (block === undefined) { diff --git a/packages/nodejs/test/testHelpers.ts b/packages/nodejs/test/testHelpers.ts index 7be347e01..f1f2fa25c 100644 --- a/packages/nodejs/test/testHelpers.ts +++ b/packages/nodejs/test/testHelpers.ts @@ -13,13 +13,17 @@ import 'isomorphic-fetch'; export { getModuleBuffer } from '../src/util'; +const TESTNET_NODE = 'node.testnet.concordium.com'; +const GRPCV1_PORT = 10000; +const GRPCV2_PORT = 20000; + /** * Creates a gRPC v1 client (for nodeJS) to communicate with a local concordium-node * used for automatic tests. */ export function getNodeClient( - address = '127.0.0.1', - port = 10000 + address = TESTNET_NODE, + port = GRPCV1_PORT ): ConcordiumNodeClient { const metadata = new Metadata(); metadata.add('authentication', 'rpcadmin'); @@ -37,8 +41,8 @@ export function getNodeClient( * used for automatic tests. */ export function getNodeClientV2( - address = 'node.testnet.concordium.com', - port = 20000 + address = TESTNET_NODE, + port = GRPCV2_PORT ): ConcordiumGRPCClient { return createConcordiumClient(address, port, credentials.createInsecure(), { timeout: 15000, @@ -52,7 +56,7 @@ export function getNodeClientV2( */ export function getNodeClientWeb( address = 'http://node.testnet.concordium.com', - port = 20000 + port = GRPCV2_PORT ): ConcordiumGRPCClient { const transport = new GrpcWebFetchTransport({ baseUrl: `${address}:${port}`,