Skip to content

Commit 34617b2

Browse files
authored
Merge pull request #285 from opentensor/Registrations_Signed_Extension_Filtering
Registrations signed extension filtering
2 parents b625c46 + a56a689 commit 34617b2

File tree

2 files changed

+194
-6
lines changed

2 files changed

+194
-6
lines changed

pallets/subtensor/src/lib.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,10 +1830,20 @@ where
18301830
priority: Self::get_priority_vanilla(),
18311831
..Default::default()
18321832
}),
1833-
Some(Call::register { .. }) => Ok(ValidTransaction {
1834-
priority: Self::get_priority_vanilla(),
1835-
..Default::default()
1836-
}),
1833+
Some(Call::register { netuid, .. } | Call::burned_register { netuid, .. }) => {
1834+
let registrations_this_interval =
1835+
Pallet::<T>::get_registrations_this_interval(*netuid);
1836+
let max_registrations_per_interval =
1837+
Pallet::<T>::get_target_registrations_per_interval(*netuid);
1838+
if registrations_this_interval >= max_registrations_per_interval {
1839+
// If the registration limit for the interval is exceeded, reject the transaction
1840+
return InvalidTransaction::ExhaustsResources.into();
1841+
}
1842+
Ok(ValidTransaction {
1843+
priority: Self::get_priority_vanilla(),
1844+
..Default::default()
1845+
})
1846+
}
18371847
Some(Call::register_network { .. }) => Ok(ValidTransaction {
18381848
priority: Self::get_priority_vanilla(),
18391849
..Default::default()

pallets/subtensor/tests/registration.rs

Lines changed: 180 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ use frame_support::traits::Currency;
22

33
use crate::mock::*;
44
use frame_support::dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays};
5-
use frame_support::sp_runtime::DispatchError;
5+
use frame_support::sp_runtime::{transaction_validity::InvalidTransaction, DispatchError};
66
use frame_support::{assert_err, assert_ok};
77
use frame_system::Config;
8-
use pallet_subtensor::{AxonInfoOf, Error};
8+
use pallet_subtensor::{AxonInfoOf, Error, SubtensorSignedExtension};
99
use sp_core::U256;
10+
use sp_runtime::traits::{DispatchInfoOf, SignedExtension};
1011

1112
mod mock;
1213

@@ -153,10 +154,187 @@ fn test_registration_ok() {
153154
});
154155
}
155156

157+
#[test]
158+
fn test_registration_under_limit() {
159+
new_test_ext().execute_with(|| {
160+
let netuid: u16 = 1;
161+
let block_number: u64 = 0;
162+
let hotkey_account_id: U256 = U256::from(1);
163+
let coldkey_account_id = U256::from(667);
164+
let who: <Test as frame_system::Config>::AccountId = hotkey_account_id;
165+
166+
let max_registrants = 2;
167+
SubtensorModule::set_target_registrations_per_interval(netuid, max_registrants);
168+
169+
let (nonce, work) = SubtensorModule::create_work_for_block_number(
170+
netuid,
171+
block_number,
172+
129123813,
173+
&hotkey_account_id,
174+
);
175+
let work_clone = work.clone();
176+
let call = pallet_subtensor::Call::register {
177+
netuid,
178+
block_number,
179+
nonce,
180+
work: work_clone,
181+
hotkey: hotkey_account_id,
182+
coldkey: coldkey_account_id,
183+
};
184+
let info: DispatchInfo =
185+
DispatchInfoOf::<<Test as frame_system::Config>::RuntimeCall>::default();
186+
let extension = SubtensorSignedExtension::<Test>::new();
187+
//does not actually call register
188+
let result = extension.validate(&who, &call.into(), &info, 10);
189+
assert_ok!(result);
190+
191+
//actually call register
192+
add_network(netuid, 13, 0);
193+
assert_ok!(SubtensorModule::register(
194+
<<Test as Config>::RuntimeOrigin>::signed(hotkey_account_id),
195+
netuid,
196+
block_number,
197+
nonce,
198+
work,
199+
hotkey_account_id,
200+
coldkey_account_id
201+
));
202+
203+
let current_registrants = SubtensorModule::get_registrations_this_interval(netuid);
204+
let target_registrants = SubtensorModule::get_target_registrations_per_interval(netuid);
205+
assert!(current_registrants <= target_registrants);
206+
});
207+
}
208+
209+
#[test]
210+
fn test_registration_rate_limit_exceeded() {
211+
new_test_ext().execute_with(|| {
212+
let netuid: u16 = 1;
213+
let block_number: u64 = 0;
214+
let hotkey_account_id: U256 = U256::from(1);
215+
let coldkey_account_id = U256::from(667);
216+
let who: <Test as frame_system::Config>::AccountId = hotkey_account_id;
217+
218+
let max_registrants = 1;
219+
SubtensorModule::set_target_registrations_per_interval(netuid, max_registrants);
220+
SubtensorModule::set_registrations_this_interval(netuid, 1);
221+
222+
let (nonce, work) = SubtensorModule::create_work_for_block_number(
223+
netuid,
224+
block_number,
225+
129123813,
226+
&hotkey_account_id,
227+
);
228+
let call = pallet_subtensor::Call::register {
229+
netuid,
230+
block_number,
231+
nonce,
232+
work,
233+
hotkey: hotkey_account_id,
234+
coldkey: coldkey_account_id,
235+
};
236+
let info: DispatchInfo =
237+
DispatchInfoOf::<<Test as frame_system::Config>::RuntimeCall>::default();
238+
let extension = SubtensorSignedExtension::<Test>::new();
239+
let result = extension.validate(&who, &call.into(), &info, 10);
240+
241+
// Expectation: The transaction should be rejected
242+
assert_err!(result, InvalidTransaction::ExhaustsResources);
243+
244+
let current_registrants = SubtensorModule::get_registrations_this_interval(netuid);
245+
assert!(current_registrants <= max_registrants);
246+
});
247+
}
248+
156249
/********************************************
157250
registration::do_burned_registration tests
158251
*********************************************/
159252

253+
#[test]
254+
fn test_burned_registration_under_limit() {
255+
new_test_ext().execute_with(|| {
256+
let netuid: u16 = 1;
257+
let hotkey_account_id: U256 = U256::from(1);
258+
let coldkey_account_id = U256::from(667);
259+
let who: <Test as frame_system::Config>::AccountId = hotkey_account_id;
260+
let block_number: u64 = 0;
261+
262+
let (nonce, work) = SubtensorModule::create_work_for_block_number(
263+
netuid,
264+
block_number,
265+
129123813,
266+
&hotkey_account_id,
267+
);
268+
269+
let max_registrants = 2;
270+
SubtensorModule::set_target_registrations_per_interval(netuid, max_registrants);
271+
272+
let call_burned_register: pallet_subtensor::Call<Test> =
273+
pallet_subtensor::Call::burned_register {
274+
netuid,
275+
hotkey: hotkey_account_id,
276+
};
277+
278+
let info: DispatchInfo =
279+
DispatchInfoOf::<<Test as frame_system::Config>::RuntimeCall>::default();
280+
let extension = SubtensorSignedExtension::<Test>::new();
281+
//does not actually call register
282+
let burned_register_result =
283+
extension.validate(&who, &call_burned_register.into(), &info, 10);
284+
assert_ok!(burned_register_result);
285+
286+
add_network(netuid, 13, 0);
287+
//actually call register
288+
assert_ok!(SubtensorModule::register(
289+
<<Test as Config>::RuntimeOrigin>::signed(hotkey_account_id),
290+
netuid,
291+
block_number,
292+
nonce,
293+
work,
294+
hotkey_account_id,
295+
coldkey_account_id
296+
));
297+
298+
let current_registrants = SubtensorModule::get_registrations_this_interval(netuid);
299+
let target_registrants = SubtensorModule::get_target_registrations_per_interval(netuid);
300+
assert!(current_registrants <= target_registrants);
301+
});
302+
}
303+
304+
#[test]
305+
fn test_burned_registration_rate_limit_exceeded() {
306+
new_test_ext().execute_with(|| {
307+
let netuid: u16 = 1;
308+
let hotkey_account_id: U256 = U256::from(1);
309+
let who: <Test as frame_system::Config>::AccountId = hotkey_account_id;
310+
let max_registrants = 1;
311+
312+
SubtensorModule::set_target_registrations_per_interval(netuid, max_registrants);
313+
SubtensorModule::set_registrations_this_interval(netuid, 1);
314+
315+
let call_burned_register: pallet_subtensor::Call<Test> =
316+
pallet_subtensor::Call::burned_register {
317+
netuid,
318+
hotkey: hotkey_account_id,
319+
};
320+
321+
let info: DispatchInfo =
322+
DispatchInfoOf::<<Test as frame_system::Config>::RuntimeCall>::default();
323+
let extension = SubtensorSignedExtension::<Test>::new();
324+
let burned_register_result =
325+
extension.validate(&who, &call_burned_register.into(), &info, 10);
326+
327+
// Expectation: The transaction should be rejected
328+
assert_err!(
329+
burned_register_result,
330+
InvalidTransaction::ExhaustsResources
331+
);
332+
333+
let current_registrants = SubtensorModule::get_registrations_this_interval(netuid);
334+
assert!(current_registrants <= max_registrants);
335+
});
336+
}
337+
160338
#[test]
161339
fn test_burned_registration_ok() {
162340
new_test_ext().execute_with(|| {

0 commit comments

Comments
 (0)