11use ark_serialize:: { CanonicalDeserialize , CanonicalSerialize } ;
22use codec:: { Decode , Encode } ;
33
4- use rand_core:: OsRng ;
4+ use rand_core:: { OsRng , RngCore } ;
55use serde:: Deserialize ;
66use sha2:: Digest ;
77use std:: os:: raw:: c_char;
@@ -14,7 +14,6 @@ use tle::{
1414} ;
1515use w3f_bls:: EngineBLS ;
1616
17- pub const SUBTENSOR_PULSE_DELAY : u64 = 24 ; //Drand rounds amount
1817const PUBLIC_KEY : & str = "83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a" ;
1918pub const GENESIS_TIME : u64 = 1692803367 ;
2019pub const DRAND_PERIOD : u64 = 3 ;
@@ -34,6 +33,7 @@ const ENDPOINTS: [&str; 5] = [
3433
3534#[ derive( Encode , Decode , Debug , PartialEq ) ]
3635pub struct WeightsTlockPayload {
36+ pub hotkey : Vec < u8 > ,
3737 pub uids : Vec < u16 > ,
3838 pub values : Vec < u16 > ,
3939 pub version_key : u64 ,
@@ -94,7 +94,8 @@ pub fn encrypt_and_compress(
9494 let identity = Identity :: new ( b"" , vec ! [ message] ) ;
9595
9696 // Encrypt payload
97- let esk = [ 2 ; 32 ] ;
97+ let mut esk = [ 0u8 ; 32 ] ;
98+ OsRng . fill_bytes ( & mut esk) ;
9899 let ct = tle :: < TinyBLS381 , AESGCMStreamCipherProvider , OsRng > (
99100 pub_key,
100101 esk,
@@ -178,6 +179,7 @@ pub fn decrypt_and_decompress(
178179/// * `netuid` - A u16 representing the network's unique identifier.
179180/// * `subnet_reveal_period_epochs` - A u64 indicating the number of epochs before reveal.
180181/// * `block_time` - Duration of each block in seconds as u64.
182+ /// * `hotkey` - The hotkey of the committing validator
181183///
182184/// # Returns
183185///
@@ -194,49 +196,66 @@ pub fn generate_commit(
194196 netuid : u16 ,
195197 subnet_reveal_period_epochs : u64 ,
196198 block_time : f64 ,
199+ hotkey : Vec < u8 > ,
197200) -> Result < ( Vec < u8 > , u64 ) , ( std:: io:: Error , String ) > {
198- // Steps comes from here https://github.com/opentensor/subtensor/pull/982/files#diff-7261bf1c7f19fc66a74c1c644ec2b4b277a341609710132fb9cd5f622350a6f5R120-R131
199-
200- // Instantiate payload
201- let payload = WeightsTlockPayload {
202- uids,
203- values,
204- version_key,
205- } ;
206- let serialized_payload = payload. encode ( ) ;
207-
208- let now = SystemTime :: now ( )
201+ //----------------------------------------------------------------------
202+ // 1 ▸ derive the first block of the reveal epoch
203+ //----------------------------------------------------------------------
204+ let tempo_plus_one = tempo. saturating_add ( 1 ) ;
205+ let netuid_plus_one = netuid as u64 + 1 ;
206+
207+ // epoch index of `current_block`
208+ let current_epoch = ( current_block + netuid_plus_one) / tempo_plus_one;
209+
210+ // epoch index in which the commit must be revealed
211+ let reveal_epoch = current_epoch + subnet_reveal_period_epochs;
212+
213+ // very first block *inside* the reveal epoch
214+ let first_reveal_blk = reveal_epoch
215+ . saturating_mul ( tempo_plus_one)
216+ . saturating_sub ( netuid_plus_one) ;
217+
218+ //----------------------------------------------------------------------
219+ // 2 ▸ decide in which *block* we want the pulse to be emitted
220+ // – we aim for first_reveal_blk + 3
221+ //----------------------------------------------------------------------
222+ pub const SECURITY_BLOCK_OFFSET : u64 = 3 ;
223+ let target_ingest_blk = first_reveal_blk. saturating_add ( SECURITY_BLOCK_OFFSET ) ;
224+ let blocks_until_ingest = target_ingest_blk. saturating_sub ( current_block) ;
225+ let secs_until_ingest = blocks_until_ingest as f64 * block_time;
226+
227+ //----------------------------------------------------------------------
228+ // 3 ▸ convert the desired timestamp into a DRAND round
229+ //----------------------------------------------------------------------
230+ let now_secs = SystemTime :: now ( )
209231 . duration_since ( UNIX_EPOCH )
210232 . unwrap ( )
211233 . as_secs_f64 ( ) ;
212234
213- let tempo_plus_one = tempo + 1 ;
214- let netuid_plus_one = ( netuid as u64 ) + 1 ;
215- let block_with_offset = current_block + netuid_plus_one;
216- let current_epoch = block_with_offset / tempo_plus_one;
217-
218- let mut reveal_epoch = current_epoch + subnet_reveal_period_epochs;
219- let mut reveal_block_number = reveal_epoch * tempo_plus_one - netuid_plus_one;
220- let mut blocks_until_reveal = reveal_block_number - current_block;
221- let mut time_until_reveal = ( blocks_until_reveal as f64 ) * block_time;
222-
223- //
224- while time_until_reveal < ( SUBTENSOR_PULSE_DELAY * DRAND_PERIOD ) as f64 {
225- reveal_epoch += 1 ;
226- reveal_block_number = reveal_epoch * tempo_plus_one - netuid_plus_one;
227- blocks_until_reveal = reveal_block_number - current_block;
228- time_until_reveal = ( blocks_until_reveal as f64 ) * block_time;
235+ let target_secs = now_secs + secs_until_ingest;
236+
237+ // Round ***down*** so we never request a not‑yet‑ingested pulse.
238+ let mut reveal_round =
239+ ( ( target_secs - GENESIS_TIME as f64 ) / DRAND_PERIOD as f64 ) . floor ( ) as u64 ;
240+
241+ if reveal_round < 1 {
242+ reveal_round = 1 ;
229243 }
230244
231- let reveal_time = now + time_until_reveal;
232- let reveal_round = ( ( reveal_time - GENESIS_TIME as f64 ) / DRAND_PERIOD as f64 ) . ceil ( ) as u64
233- - SUBTENSOR_PULSE_DELAY ;
245+ //----------------------------------------------------------------------
246+ // 5 ▸ build & encrypt payload
247+ //----------------------------------------------------------------------
248+ let payload = WeightsTlockPayload {
249+ hotkey,
250+ uids,
251+ values,
252+ version_key,
253+ } ;
234254
235- let ct_bytes = encrypt_and_compress ( & serialized_payload , reveal_round) ?;
255+ let ct_bytes = encrypt_and_compress ( & payload . encode ( ) , reveal_round) ?;
236256
237257 Ok ( ( ct_bytes, reveal_round) )
238258}
239-
240259/// Encrypts a string-based commitment using Drand timelock encryption for a future reveal round.
241260///
242261/// This function encodes the input `data` and calculates the corresponding Drand round number
@@ -470,6 +489,7 @@ mod tests {
470489 let current_block = 1000 ;
471490 let netuid = 1 ;
472491 let reveal_epochs = 3 ;
492+ let hotkey = vec ! [ 1 , 2 , 3 ] ;
473493
474494 let ( encrypted, reveal_round) = generate_commit (
475495 uids. clone ( ) ,
@@ -480,6 +500,7 @@ mod tests {
480500 netuid,
481501 reveal_epochs,
482502 12.0 ,
503+ hotkey. clone ( ) ,
483504 )
484505 . expect ( "Commit generation failed" ) ;
485506
@@ -499,6 +520,7 @@ mod tests {
499520 assert_eq ! ( payload. uids, uids) ;
500521 assert_eq ! ( payload. values, values) ;
501522 assert_eq ! ( payload. version_key, version_key) ;
523+ assert_eq ! ( payload. hotkey, hotkey)
502524 }
503525 }
504526}
0 commit comments