Skip to content

Commit babfda3

Browse files
authored
Merge pull request #1356 from opentensor/feat/staking-precompile-v2
Add StakingPrecompileV2
2 parents f7c001b + 83d100d commit babfda3

File tree

9 files changed

+452
-36
lines changed

9 files changed

+452
-36
lines changed

precompiles/src/balance_transfer.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ where
2424
<R as pallet_balances::Config>::Balance: TryFrom<U256>,
2525
{
2626
const INDEX: u64 = 2048;
27-
const ADDRESS_SS58: [u8; 32] = [
27+
const ADDRESS_SS58: Option<[u8; 32]> = Some([
2828
0x07, 0xec, 0x71, 0x2a, 0x5d, 0x38, 0x43, 0x4d, 0xdd, 0x03, 0x3f, 0x8f, 0x02, 0x4e, 0xcd,
2929
0xfc, 0x4b, 0xb5, 0x95, 0x1c, 0x13, 0xc3, 0x08, 0x5c, 0x39, 0x9c, 0x8a, 0x5f, 0x62, 0x93,
3030
0x70, 0x5d,
31-
];
31+
]);
3232
}
3333

3434
#[precompile_utils::precompile]
@@ -60,6 +60,11 @@ where
6060
value: amount_sub.unique_saturated_into(),
6161
};
6262

63-
handle.try_dispatch_runtime_call::<R, _>(call, contract_to_origin(&Self::ADDRESS_SS58)?)
63+
handle.try_dispatch_runtime_call::<R, _>(
64+
call,
65+
contract_to_origin(
66+
&Self::ADDRESS_SS58.expect("ADDRESS_SS58 is defined for BalanceTransferPrecompile"),
67+
)?,
68+
)
6469
}
6570
}

precompiles/src/ed25519.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub(crate) struct Ed25519Verify;
1212

1313
impl PrecompileExt for Ed25519Verify {
1414
const INDEX: u64 = 1026;
15-
const ADDRESS_SS58: [u8; 32] = [0; 32];
15+
const ADDRESS_SS58: Option<[u8; 32]> = None;
1616
}
1717

1818
impl LinearCostPrecompile for Ed25519Verify {

precompiles/src/lib.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ where
8686
Self(Default::default())
8787
}
8888

89-
pub fn used_addresses() -> [H160; 13] {
89+
pub fn used_addresses() -> [H160; 14] {
9090
[
9191
hash(1),
9292
hash(2),
@@ -101,6 +101,7 @@ where
101101
hash(SubnetPrecompile::<R>::INDEX),
102102
hash(MetagraphPrecompile::<R>::INDEX),
103103
hash(NeuronPrecompile::<R>::INDEX),
104+
hash(StakingPrecompileV2::<R>::INDEX),
104105
]
105106
}
106107
}
@@ -152,9 +153,16 @@ where
152153
Some(StakingPrecompile::<R>::execute(handle))
153154
} else {
154155
Some(Err(PrecompileFailure::Error {
155-
exit_status: ExitError::Other(
156-
"Precompile Balance Transfer is disabled".into(),
157-
),
156+
exit_status: ExitError::Other("Precompile Staking is disabled".into()),
157+
}))
158+
}
159+
}
160+
a if a == hash(StakingPrecompileV2::<R>::INDEX) => {
161+
if PrecompileEnable::<R>::get(PrecompileEnum::Staking) {
162+
Some(StakingPrecompileV2::<R>::execute(handle))
163+
} else {
164+
Some(Err(PrecompileFailure::Error {
165+
exit_status: ExitError::Other("Precompile Staking is disabled".into()),
158166
}))
159167
}
160168
}
@@ -302,5 +310,5 @@ trait PrecompileExt: Precompile {
302310
const INDEX: u64;
303311
// ss58 public key i.e., the contract sends funds it received to the destination address from
304312
// the method parameter.
305-
const ADDRESS_SS58: [u8; 32];
313+
const ADDRESS_SS58: Option<[u8; 32]>;
306314
}

precompiles/src/metagraph.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ where
1616
R::AccountId: ByteArray,
1717
{
1818
const INDEX: u64 = 2050;
19-
const ADDRESS_SS58: [u8; 32] = [0; 32];
19+
const ADDRESS_SS58: Option<[u8; 32]> = None;
2020
}
2121

2222
#[precompile_utils::precompile]

precompiles/src/neuron.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ where
2323
<R as pallet_evm::Config>::AddressMapping: AddressMapping<R::AccountId>,
2424
{
2525
const INDEX: u64 = 2052;
26-
const ADDRESS_SS58: [u8; 32] = [
26+
const ADDRESS_SS58: Option<[u8; 32]> = Some([
2727
0xbc, 0x46, 0x35, 0x79, 0xbc, 0x99, 0xf9, 0xee, 0x7c, 0x59, 0xed, 0xee, 0x20, 0x61, 0xa3,
2828
0x09, 0xd2, 0x1e, 0x68, 0xd5, 0x39, 0xb6, 0x40, 0xec, 0x66, 0x46, 0x90, 0x30, 0xab, 0x74,
2929
0xc1, 0xdb,
30-
];
30+
]);
3131
}
3232

3333
#[precompile_utils::precompile]
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
[
2+
{
3+
"inputs": [
4+
{
5+
"internalType": "bytes32",
6+
"name": "delegate",
7+
"type": "bytes32"
8+
}
9+
],
10+
"name": "addProxy",
11+
"outputs": [],
12+
"stateMutability": "nonpayable",
13+
"type": "function"
14+
},
15+
{
16+
"inputs": [
17+
{
18+
"internalType": "bytes32",
19+
"name": "hotkey",
20+
"type": "bytes32"
21+
},
22+
{
23+
"internalType": "uint256",
24+
"name": "amount",
25+
"type": "uint256"
26+
},
27+
{
28+
"internalType": "uint256",
29+
"name": "netuid",
30+
"type": "uint256"
31+
}
32+
],
33+
"name": "addStake",
34+
"outputs": [],
35+
"stateMutability": "payable",
36+
"type": "function"
37+
},
38+
{
39+
"inputs": [
40+
{
41+
"internalType": "bytes32",
42+
"name": "hotkey",
43+
"type": "bytes32"
44+
},
45+
{
46+
"internalType": "bytes32",
47+
"name": "coldkey",
48+
"type": "bytes32"
49+
},
50+
{
51+
"internalType": "uint256",
52+
"name": "netuid",
53+
"type": "uint256"
54+
}
55+
],
56+
"name": "getStake",
57+
"outputs": [
58+
{
59+
"internalType": "uint256",
60+
"name": "",
61+
"type": "uint256"
62+
}
63+
],
64+
"stateMutability": "view",
65+
"type": "function"
66+
},
67+
{
68+
"inputs": [
69+
{
70+
"internalType": "bytes32",
71+
"name": "coldkey",
72+
"type": "bytes32"
73+
}
74+
],
75+
"name": "getTotalColdkeyStake",
76+
"outputs": [
77+
{
78+
"internalType": "uint256",
79+
"name": "",
80+
"type": "uint256"
81+
}
82+
],
83+
"stateMutability": "view",
84+
"type": "function"
85+
},
86+
{
87+
"inputs": [
88+
{
89+
"internalType": "bytes32",
90+
"name": "hotkey",
91+
"type": "bytes32"
92+
}
93+
],
94+
"name": "getTotalHotkeyStake",
95+
"outputs": [
96+
{
97+
"internalType": "uint256",
98+
"name": "",
99+
"type": "uint256"
100+
}
101+
],
102+
"stateMutability": "view",
103+
"type": "function"
104+
},
105+
{
106+
"inputs": [
107+
{
108+
"internalType": "bytes32",
109+
"name": "delegate",
110+
"type": "bytes32"
111+
}
112+
],
113+
"name": "removeProxy",
114+
"outputs": [],
115+
"stateMutability": "nonpayable",
116+
"type": "function"
117+
},
118+
{
119+
"inputs": [
120+
{
121+
"internalType": "bytes32",
122+
"name": "hotkey",
123+
"type": "bytes32"
124+
},
125+
{
126+
"internalType": "uint256",
127+
"name": "amount",
128+
"type": "uint256"
129+
},
130+
{
131+
"internalType": "uint256",
132+
"name": "netuid",
133+
"type": "uint256"
134+
}
135+
],
136+
"name": "removeStake",
137+
"outputs": [],
138+
"stateMutability": "nonpayable",
139+
"type": "function"
140+
}
141+
]
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
pragma solidity ^0.8.0;
2+
3+
address constant ISTAKING_ADDRESS = 0x0000000000000000000000000000000000000805;
4+
5+
interface IStaking {
6+
/**
7+
* @dev Adds a subtensor stake `amount` associated with the `hotkey`.
8+
*
9+
* This function allows external accounts and contracts to stake TAO into the subtensor pallet,
10+
* which effectively calls `add_stake` on the subtensor pallet with specified hotkey as a parameter
11+
* and coldkey being the hashed address mapping of H160 sender address to Substrate ss58 address as
12+
* implemented in Frontier HashedAddressMapping:
13+
* https://github.com/polkadot-evm/frontier/blob/2e219e17a526125da003e64ef22ec037917083fa/frame/evm/src/lib.rs#L739
14+
*
15+
* @param hotkey The hotkey public key (32 bytes).
16+
* @param amount The amount to stake in rao.
17+
* @param netuid The subnet to stake to (uint256).
18+
*
19+
* Requirements:
20+
* - `hotkey` must be a valid hotkey registered on the network, ensuring that the stake is
21+
* correctly attributed.
22+
*/
23+
function addStake(bytes32 hotkey, uint256 amount, uint256 netuid) external payable;
24+
25+
/**
26+
* @dev Removes a subtensor stake `amount` from the specified `hotkey`.
27+
*
28+
* This function allows external accounts and contracts to unstake TAO from the subtensor pallet,
29+
* which effectively calls `remove_stake` on the subtensor pallet with specified hotkey as a parameter
30+
* and coldkey being the hashed address mapping of H160 sender address to Substrate ss58 address as
31+
* implemented in Frontier HashedAddressMapping:
32+
* https://github.com/polkadot-evm/frontier/blob/2e219e17a526125da003e64ef22ec037917083fa/frame/evm/src/lib.rs#L739
33+
*
34+
* @param hotkey The hotkey public key (32 bytes).
35+
* @param amount The amount to unstake in alpha.
36+
* @param netuid The subnet to stake to (uint256).
37+
*
38+
* Requirements:
39+
* - `hotkey` must be a valid hotkey registered on the network, ensuring that the stake is
40+
* correctly attributed.
41+
* - The existing stake amount must be not lower than specified amount
42+
*/
43+
function removeStake(
44+
bytes32 hotkey,
45+
uint256 amount,
46+
uint256 netuid
47+
) external;
48+
49+
/**
50+
* @dev Returns the amount of RAO staked by the coldkey.
51+
*
52+
* This function allows external accounts and contracts to query the amount of RAO staked by the coldkey
53+
* which effectively calls `get_total_coldkey_stake` on the subtensor pallet with
54+
* specified coldkey as a parameter.
55+
*
56+
* @param coldkey The coldkey public key (32 bytes).
57+
* @return The amount of RAO staked by the coldkey.
58+
*/
59+
function getTotalColdkeyStake(bytes32 coldkey) external view returns (uint256);
60+
61+
/**
62+
* @dev Returns the total amount of stake under a hotkey (delegative or otherwise)
63+
*
64+
* This function allows external accounts and contracts to query the total amount of RAO staked under a hotkey
65+
* which effectively calls `get_total_hotkey_stake` on the subtensor pallet with
66+
* specified hotkey as a parameter.
67+
*
68+
* @param hotkey The hotkey public key (32 bytes).
69+
* @return The total amount of RAO staked under the hotkey.
70+
*/
71+
function getTotalHotkeyStake(bytes32 hotkey) external view returns (uint256);
72+
73+
/**
74+
* @dev Returns the stake amount associated with the specified `hotkey` and `coldkey`.
75+
*
76+
* This function retrieves the current stake amount linked to a specific hotkey and coldkey pair.
77+
* It is a view function, meaning it does not modify the state of the contract and is free to call.
78+
*
79+
* @param hotkey The hotkey public key (32 bytes).
80+
* @param coldkey The coldkey public key (32 bytes).
81+
* @param netuid The subnet the stake is on (uint256).
82+
* @return The current stake amount in uint256 format.
83+
*/
84+
function getStake(
85+
bytes32 hotkey,
86+
bytes32 coldkey,
87+
uint256 netuid
88+
) external view returns (uint256);
89+
90+
/**
91+
* @dev Delegates staking to a proxy account.
92+
*
93+
* @param delegate The public key (32 bytes) of the delegate.
94+
*/
95+
function addProxy(bytes32 delegate) external;
96+
97+
/**
98+
* @dev Removes staking proxy account.
99+
*
100+
* @param delegate The public key (32 bytes) of the delegate.
101+
*/
102+
function removeProxy(bytes32 delegate) external;
103+
}

0 commit comments

Comments
 (0)