Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions common/src/transaction_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub enum CustomTransactionError {
InvalidRealAccount,
FailedShieldedTxParsing,
InvalidShieldedTxPubKeyHash,
NonAssociatedColdKey,
}

impl From<CustomTransactionError> for u8 {
Expand Down Expand Up @@ -62,6 +63,7 @@ impl From<CustomTransactionError> for u8 {
CustomTransactionError::InvalidRealAccount => 22,
CustomTransactionError::FailedShieldedTxParsing => 23,
CustomTransactionError::InvalidShieldedTxPubKeyHash => 24,
CustomTransactionError::NonAssociatedColdKey => 25,
}
}
}
Expand Down
232 changes: 190 additions & 42 deletions pallets/subtensor/src/extensions/subtensor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,12 @@ where
}

pub fn result_to_validity(result: Result<(), Error<T>>, priority: u64) -> TransactionValidity {
if let Err(err) = result {
Err(match err {
match result {
Ok(()) => Ok(ValidTransaction {
priority,
..Default::default()
}),
Err(err) => Err(match err {
Error::<T>::AmountTooLow => CustomTransactionError::StakeAmountTooLow,
Error::<T>::SubnetNotExists => CustomTransactionError::SubnetNotExists,
Error::<T>::NotEnoughBalanceToStake => CustomTransactionError::BalanceTooLow,
Expand All @@ -73,14 +77,10 @@ where
CustomTransactionError::ServingRateLimitExceeded
}
Error::<T>::InvalidPort => CustomTransactionError::InvalidPort,
Error::<T>::NonAssociatedColdKey => CustomTransactionError::NonAssociatedColdKey,
_ => CustomTransactionError::BadRequest,
}
.into())
} else {
Ok(ValidTransaction {
priority,
..Default::default()
})
.into()),
}
}
}
Expand Down Expand Up @@ -115,13 +115,29 @@ where
};

match call.is_sub_type() {
Some(Call::commit_weights { netuid, .. }) => {
Some(Call::commit_weights { netuid, .. })
| Some(Call::commit_mechanism_weights { netuid, .. }) => {
if Self::check_weights_min_stake(who, *netuid) {
Ok((Default::default(), (), origin))
} else {
Err(CustomTransactionError::StakeAmountTooLow.into())
}
}
Some(Call::batch_commit_weights {
netuids,
commit_hashes,
}) => {
if netuids.len() != commit_hashes.len() {
return Err(CustomTransactionError::InputLengthsUnequal.into());
}
for netuid in netuids.iter() {
let netuid: NetUid = (*netuid).into();
if !Self::check_weights_min_stake(who, netuid) {
return Err(CustomTransactionError::StakeAmountTooLow.into());
}
}
Ok((Default::default(), (), origin))
}
Some(Call::reveal_weights {
netuid,
uids,
Expand Down Expand Up @@ -152,61 +168,108 @@ where
Err(CustomTransactionError::StakeAmountTooLow.into())
}
}
Some(Call::reveal_mechanism_weights {
netuid,
mecid: _,
uids,
values,
salt,
version_key,
}) => {
if Self::check_weights_min_stake(who, *netuid) {
let provided_hash = Pallet::<T>::get_commit_hash(
who,
NetUidStorageIndex::from(*netuid),
uids,
values,
salt,
*version_key,
);
match Pallet::<T>::find_commit_block_via_hash(provided_hash) {
Some(commit_block) => {
if Pallet::<T>::is_reveal_block_range(*netuid, commit_block) {
Ok((Default::default(), (), origin))
} else {
Err(CustomTransactionError::CommitBlockNotInRevealRange.into())
}
}
None => Err(CustomTransactionError::CommitNotFound.into()),
}
} else {
Err(CustomTransactionError::StakeAmountTooLow.into())
}
}
Some(Call::batch_reveal_weights {
netuid,
uids_list,
values_list,
salts_list,
version_keys,
}) => {
if Self::check_weights_min_stake(who, *netuid) {
let num_reveals = uids_list.len();
if num_reveals == values_list.len()
&& num_reveals == salts_list.len()
&& num_reveals == version_keys.len()
{
let provided_hashes = (0..num_reveals)
.map(|i| {
Pallet::<T>::get_commit_hash(
who,
NetUidStorageIndex::from(*netuid),
uids_list.get(i).unwrap_or(&Vec::new()),
values_list.get(i).unwrap_or(&Vec::new()),
salts_list.get(i).unwrap_or(&Vec::new()),
*version_keys.get(i).unwrap_or(&0_u64),
)
})
.collect::<Vec<_>>();
if !Self::check_weights_min_stake(who, *netuid) {
return Err(CustomTransactionError::StakeAmountTooLow.into());
}

let batch_reveal_block = provided_hashes
.iter()
.filter_map(|hash| Pallet::<T>::find_commit_block_via_hash(*hash))
.collect::<Vec<_>>();
let num_reveals = uids_list.len();
if num_reveals == values_list.len()
&& num_reveals == salts_list.len()
&& num_reveals == version_keys.len()
{
let provided_hashes = (0..num_reveals)
.map(|i| {
Pallet::<T>::get_commit_hash(
who,
NetUidStorageIndex::from(*netuid),
uids_list.get(i).unwrap_or(&Vec::new()),
values_list.get(i).unwrap_or(&Vec::new()),
salts_list.get(i).unwrap_or(&Vec::new()),
*version_keys.get(i).unwrap_or(&0_u64),
)
})
.collect::<Vec<_>>();

if provided_hashes.len() == batch_reveal_block.len() {
if Pallet::<T>::is_batch_reveal_block_range(*netuid, batch_reveal_block)
{
Ok((Default::default(), (), origin))
} else {
Err(CustomTransactionError::CommitBlockNotInRevealRange.into())
}
let batch_reveal_block = provided_hashes
.iter()
.filter_map(|hash| Pallet::<T>::find_commit_block_via_hash(*hash))
.collect::<Vec<_>>();

if provided_hashes.len() == batch_reveal_block.len() {
if Pallet::<T>::is_batch_reveal_block_range(*netuid, batch_reveal_block) {
Ok((Default::default(), (), origin))
} else {
Err(CustomTransactionError::CommitNotFound.into())
Err(CustomTransactionError::CommitBlockNotInRevealRange.into())
}
} else {
Err(CustomTransactionError::InputLengthsUnequal.into())
Err(CustomTransactionError::CommitNotFound.into())
}
} else {
Err(CustomTransactionError::StakeAmountTooLow.into())
Err(CustomTransactionError::InputLengthsUnequal.into())
}
}
Some(Call::set_weights { netuid, .. }) => {
Some(Call::set_weights { netuid, .. })
| Some(Call::set_mechanism_weights { netuid, .. }) => {
if Self::check_weights_min_stake(who, *netuid) {
Ok((Default::default(), (), origin))
} else {
Err(CustomTransactionError::StakeAmountTooLow.into())
}
}
Some(Call::batch_set_weights {
netuids,
weights,
version_keys,
}) => {
if netuids.len() != weights.len() || netuids.len() != version_keys.len() {
return Err(CustomTransactionError::InputLengthsUnequal.into());
}
for netuid in netuids.iter() {
let netuid: NetUid = (*netuid).into();
if !Self::check_weights_min_stake(who, netuid) {
return Err(CustomTransactionError::StakeAmountTooLow.into());
}
}
Ok((Default::default(), (), origin))
}
Some(Call::commit_timelocked_weights {
netuid,
reveal_round,
Expand All @@ -221,6 +284,52 @@ where
Err(CustomTransactionError::StakeAmountTooLow.into())
}
}
Some(Call::commit_timelocked_mechanism_weights {
netuid,
mecid: _,
reveal_round,
..
})
| Some(Call::commit_crv3_mechanism_weights {
netuid,
mecid: _,
reveal_round,
..
}) => {
if Self::check_weights_min_stake(who, *netuid) {
if *reveal_round < pallet_drand::LastStoredRound::<T>::get() {
return Err(CustomTransactionError::InvalidRevealRound.into());
}
Ok((Default::default(), (), origin))
} else {
Err(CustomTransactionError::StakeAmountTooLow.into())
}
}
Some(Call::increase_take { hotkey, take: _ })
| Some(Call::decrease_take { hotkey, take: _ }) => {
Self::result_to_validity(Pallet::<T>::do_take_checks(who, hotkey), 0u64)
.map(|validity| (validity, (), origin.clone()))
}

Some(Call::swap_hotkey_v2 {
hotkey,
new_hotkey: _,
netuid: _,
keep_stake: _,
}) => {
if !Pallet::<T>::coldkey_owns_hotkey(who, hotkey) {
return Err(CustomTransactionError::NonAssociatedColdKey.into());
}

let block: u64 = Pallet::<T>::get_current_block_as_u64();

if Pallet::<T>::exceeds_tx_rate_limit(Pallet::<T>::get_last_tx_block(who), block) {
return Err(CustomTransactionError::RateLimitExceeded.into());
}

Ok((Default::default(), (), origin))
}

Some(Call::serve_axon {
netuid,
version,
Expand Down Expand Up @@ -248,6 +357,45 @@ where
)
.map(|validity| (validity, (), origin.clone()))
}
Some(Call::serve_axon_tls {
netuid,
version,
ip,
port,
ip_type,
protocol,
placeholder1,
placeholder2,
certificate: _,
}) => Self::result_to_validity(
Pallet::<T>::validate_serve_axon(
who,
*netuid,
*version,
*ip,
*port,
*ip_type,
*protocol,
*placeholder1,
*placeholder2,
),
0u64,
)
.map(|validity| (validity, (), origin.clone())),
Some(Call::serve_prometheus {
netuid,
version,
ip,
port,
ip_type,
}) => Self::result_to_validity(
Pallet::<T>::validate_serve_prometheus(
who, *netuid, *version, *ip, *port, *ip_type,
)
.map(|_| ()),
0u64,
)
.map(|validity| (validity, (), origin.clone())),
Some(Call::register_network { .. }) => {
if !TransactionType::RegisterNetwork.passes_rate_limit::<T>(who) {
return Err(CustomTransactionError::RateLimitExceeded.into());
Expand Down
Loading
Loading