From 9e4da4c73a11b38caeb645f6a73f752487122edb Mon Sep 17 00:00:00 2001 From: Jesse Abramowitz Date: Wed, 21 Aug 2024 16:12:35 -0400 Subject: [PATCH] add rotate keyshare trigger to chain --- node/cli/src/service.rs | 5 ++++ pallets/propagation/src/lib.rs | 47 ++++++++++++++++++++++++++++++++ pallets/propagation/src/tests.rs | 11 ++++++++ pallets/staking/src/lib.rs | 6 ++++ 4 files changed, 69 insertions(+) diff --git a/node/cli/src/service.rs b/node/cli/src/service.rs index 72e7fac5b..0dbb6a88e 100644 --- a/node/cli/src/service.rs +++ b/node/cli/src/service.rs @@ -372,6 +372,11 @@ pub fn new_full_base( b"reshare_validators", &format!("{}/validator/reshare", endpoint).into_bytes(), ); + offchain_db.local_storage_set( + sp_core::offchain::StorageKind::PERSISTENT, + b"rotate_keyshares", + &format!("{}/validator/rotate_keyshares", endpoint).into_bytes(), + ); offchain_db.local_storage_set( sp_core::offchain::StorageKind::PERSISTENT, b"attest", diff --git a/pallets/propagation/src/lib.rs b/pallets/propagation/src/lib.rs index 31424c5bf..06326276e 100644 --- a/pallets/propagation/src/lib.rs +++ b/pallets/propagation/src/lib.rs @@ -98,6 +98,10 @@ pub mod pallet { /// Attestations request message passed AttestationRequestMessagePassed(OcwMessageAttestationRequest), + + /// Key Rotate Message passed to validators + /// parameters. [BlockNumberFor] + KeyRotatesMessagePassed(BlockNumberFor), } #[pallet::call] @@ -319,6 +323,49 @@ pub mod pallet { Ok(()) } + /// Submits a request to rotate parent network key the threshold servers. + pub fn post_rotate_keyshare(block_number: BlockNumberFor) -> Result<(), http::Error> { + let rotate_keyshares = pallet_staking_extension::Pallet::::rotate_keyshares(); + if !rotate_keyshares { + return Ok(()); + } + + let deadline = sp_io::offchain::timestamp().add(Duration::from_millis(2_000)); + let kind = sp_core::offchain::StorageKind::PERSISTENT; + let from_local = sp_io::offchain::local_storage_get(kind, b"rotate_keyshares") + .unwrap_or_else(|| b"http://localhost:3001/validator/rotate_keyshares".to_vec()); + let url = str::from_utf8(&from_local) + .unwrap_or("http://localhost:3001/validator/rotate_keyshares"); + + log::warn!("propagation::post rotate keyshare"); + + let converted_block_number: u32 = + BlockNumberFor::::try_into(block_number).unwrap_or_default(); + + // We construct the request + // important: the header->Content-Type must be added and match that of the receiving + // party!! + let pending = http::Request::post(url, vec![converted_block_number.encode()]) + .deadline(deadline) + .send() + .map_err(|_| http::Error::IoError)?; + + // We await response, same as in fn get() + let response = + pending.try_wait(deadline).map_err(|_| http::Error::DeadlineReached)??; + + // check response code + if response.code != 200 { + log::warn!("Unexpected status code: {}", response.code); + return Err(http::Error::Unknown); + } + let _res_body = response.body().collect::>(); + + Self::deposit_event(Event::KeyRotatesMessagePassed(block_number)); + + Ok(()) + } + /// Submits a request for a TDX attestation. pub fn post_attestation_request( block_number: BlockNumberFor, diff --git a/pallets/propagation/src/tests.rs b/pallets/propagation/src/tests.rs index b3e411e11..857f2b705 100644 --- a/pallets/propagation/src/tests.rs +++ b/pallets/propagation/src/tests.rs @@ -81,6 +81,14 @@ fn knows_how_to_mock_several_http_calls() { body: [32, 1, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0].to_vec(), ..Default::default() }); + state.expect_request(testing::PendingRequest { + method: "POST".into(), + uri: "http://localhost:3001/validator/rotate_keyshares".into(), + sent: true, + response: Some([].to_vec()), + body: [10, 0, 0, 0].to_vec(), + ..Default::default() + }); }); t.execute_with(|| { @@ -137,6 +145,9 @@ fn knows_how_to_mock_several_http_calls() { }); // now triggers Propagation::post_reshare(7).unwrap(); + + pallet_staking_extension::RotateKeyshares::::put(true); + Propagation::post_rotate_keyshare(10).unwrap(); }) } diff --git a/pallets/staking/src/lib.rs b/pallets/staking/src/lib.rs index 38d357f1f..c67308f74 100644 --- a/pallets/staking/src/lib.rs +++ b/pallets/staking/src/lib.rs @@ -230,6 +230,11 @@ pub mod pallet { #[pallet::getter(fn jump_start_progress)] pub type JumpStartProgress = StorageValue<_, JumpStartDetails, ValueQuery>; + /// Tell Signers to rotate keyshare + #[pallet::storage] + #[pallet::getter(fn rotate_keyshares)] + pub type RotateKeyshares = StorageValue<_, bool, ValueQuery>; + /// A type used to simplify the genesis configuration definition. pub type ThresholdServersConfig = ( ::ValidatorId, @@ -505,6 +510,7 @@ pub mod pallet { let current_signer_length = signers_info.next_signers.len(); if signers_info.confirmations.len() == (current_signer_length - 1) { Signers::::put(signers_info.next_signers.clone()); + RotateKeyshares::::put(true); Self::deposit_event(Event::SignersRotation(signers_info.next_signers)); Ok(Pays::No.into()) } else {