Skip to content
Merged
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
3 changes: 2 additions & 1 deletion evm-tests/test/evm-uid.precompile.lookup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,12 @@ describe("Test the UID Lookup precompile", () => {
const signature = await evmWallet.signMessage(concatenatedArray);
const associateEvmKeyTx = api.tx.SubtensorModule.associate_evm_key({
netuid: netuid,
hotkey: convertPublicKeyToSs58(hotkey.publicKey),
evm_key: convertToFixedSizeBinary(evmWallet.address, 20),
block_number: BigInt(blockNumber),
signature: convertToFixedSizeBinary(signature, 65)
});
const signer = getSignerFromKeypair(hotkey);
const signer = getSignerFromKeypair(coldkey);
await waitForTransactionCompletion(api, associateEvmKeyTx, signer)
.then(() => { })
.catch((error) => { console.log(`transaction error ${error}`) });
Expand Down
3 changes: 2 additions & 1 deletion pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2048,11 +2048,12 @@ mod dispatches {
pub fn associate_evm_key(
origin: T::RuntimeOrigin,
netuid: NetUid,
hotkey: T::AccountId,
evm_key: H160,
block_number: u64,
signature: Signature,
) -> DispatchResult {
Self::do_associate_evm_key(origin, netuid, evm_key, block_number, signature)
Self::do_associate_evm_key(origin, netuid, hotkey, evm_key, block_number, signature)
}

/// Recycles alpha from a cold/hot key pair, reducing AlphaOut on a subnet
Expand Down
49 changes: 45 additions & 4 deletions pallets/subtensor/src/tests/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ fn test_associate_evm_key_success() {
let signature = sign_evm_message(&pair, message);

assert_ok!(SubtensorModule::associate_evm_key(
RuntimeOrigin::signed(hotkey),
RuntimeOrigin::signed(coldkey),
netuid,
hotkey,
evm_key,
block_number,
signature,
Expand Down Expand Up @@ -104,8 +105,9 @@ fn test_associate_evm_key_different_block_number_success() {
let signature = sign_evm_message(&pair, message);

assert_ok!(SubtensorModule::associate_evm_key(
RuntimeOrigin::signed(hotkey),
RuntimeOrigin::signed(coldkey),
netuid,
hotkey,
evm_key,
block_number,
signature,
Expand All @@ -123,6 +125,43 @@ fn test_associate_evm_key_different_block_number_success() {
});
}

#[test]
fn test_associate_evm_key_coldkey_does_not_own_hotkey() {
new_test_ext(1).execute_with(|| {
let netuid = NetUid::from(1);

let tempo: u16 = 2;
let modality: u16 = 2;

add_network(netuid, tempo, modality);

let coldkey = U256::from(1);
let hotkey = U256::from(2);

let pair = ecdsa::Pair::generate().0;
let public = pair.public();
let evm_key = public_to_evm_key(&public);
let block_number = frame_system::Pallet::<Test>::block_number();
let hashed_block_number = keccak_256(block_number.encode().as_ref());
let hotkey_bytes = hotkey.encode();

let message = [hotkey_bytes.as_ref(), hashed_block_number.as_ref()].concat();
let signature = sign_evm_message(&pair, message);

assert_err!(
SubtensorModule::associate_evm_key(
RuntimeOrigin::signed(coldkey),
netuid,
hotkey,
evm_key,
block_number,
signature,
),
Error::<Test>::NonAssociatedColdKey
);
});
}

#[test]
fn test_associate_evm_key_hotkey_not_registered_in_subnet() {
new_test_ext(1).execute_with(|| {
Expand All @@ -149,8 +188,9 @@ fn test_associate_evm_key_hotkey_not_registered_in_subnet() {

assert_err!(
SubtensorModule::associate_evm_key(
RuntimeOrigin::signed(hotkey),
RuntimeOrigin::signed(coldkey),
netuid,
hotkey,
evm_key,
block_number,
signature,
Expand Down Expand Up @@ -189,8 +229,9 @@ fn test_associate_evm_key_using_wrong_hash_function() {

assert_err!(
SubtensorModule::associate_evm_key(
RuntimeOrigin::signed(hotkey),
RuntimeOrigin::signed(coldkey),
netuid,
hotkey,
evm_key,
block_number,
signature,
Expand Down
20 changes: 14 additions & 6 deletions pallets/subtensor/src/utils/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ impl<T: Config> Pallet<T> {

/// Associate an EVM key with a hotkey.
///
/// This function accepts a Signature, which is a signed message containing the hotkey concatenated with
/// the hashed block number. It will then attempt to recover the EVM key from the signature and compare it
/// with the `evm_key` parameter, and ensures that they match.
/// This function accepts a Signature, which is a signed message containing the hotkey
/// concatenated with the hashed block number. It will then attempt to recover the EVM key from
/// the signature and compare it with the `evm_key` parameter, and ensures that they match.
///
/// The EVM key is expected to sign the message according to this formula to produce the signature:
/// The EVM key is expected to sign the message according to this formula to produce the
/// signature:
/// ```text
/// keccak_256(hotkey ++ keccak_256(block_number))
/// ```
Expand All @@ -40,15 +41,22 @@ impl<T: Config> Pallet<T> {
/// * `hotkey` - The hotkey associated with the `origin` coldkey.
/// * `evm_key` - The EVM address to associate with the `hotkey`.
/// * `block_number` - The block number used in the `signature`.
/// * `signature` - A signed message by the `evm_key` containing the `hotkey` and the hashed `block_number`.
/// * `signature` - A signed message by the `evm_key` containing the `hotkey` and the hashed
/// `block_number`.
pub fn do_associate_evm_key(
origin: T::RuntimeOrigin,
netuid: NetUid,
hotkey: T::AccountId,
evm_key: H160,
block_number: u64,
mut signature: Signature,
) -> dispatch::DispatchResult {
let hotkey = ensure_signed(origin)?;
let coldkey = ensure_signed(origin)?;

ensure!(
Self::get_owning_coldkey_for_hotkey(&hotkey) == coldkey,
Error::<T>::NonAssociatedColdKey
);

// Normalize the v value to 0 or 1
if signature.0[64] >= 27 {
Expand Down
Loading