diff --git a/ts-tests/ink/bittensor.json b/ts-tests/ink/bittensor.json index 1a543547bc..7ab8775834 100644 --- a/ts-tests/ink/bittensor.json +++ b/ts-tests/ink/bittensor.json @@ -1,6 +1,6 @@ { "source": { - "hash": "0x69edf9f009ca08b785fad0aacb75a1d8ddad6d231848c8ca12b75f0bfc943b86", + "hash": "0xf5ded81165b29a8cdd592d22291ba8275aa9898162d916d6f3afdfe8bd7e5243", "language": "ink! 5.1.1", "compiler": "rustc 1.89.0", "build_info": { @@ -76,19 +76,19 @@ "displayName": [ "BlockNumber" ], - "type": 23 + "type": 34 }, "chainExtension": { "displayName": [ "ChainExtension" ], - "type": 24 + "type": 35 }, "hash": { "displayName": [ "Hash" ], - "type": 22 + "type": 33 }, "maxEventTopics": 4, "staticBufferSize": 16384, @@ -1563,6 +1563,98 @@ "type": 17 }, "selector": "0x59392a8e" + }, + { + "args": [ + { + "label": "netuid", + "type": { + "displayName": [ + "u16" + ], + "type": 6 + } + } + ], + "default": false, + "docs": [], + "label": "get_subnet_registration_state", + "mutates": false, + "payable": false, + "returnType": { + "displayName": [ + "ink", + "MessageResult" + ], + "type": 22 + }, + "selector": "0x2244b542" + }, + { + "args": [ + { + "label": "coldkey", + "type": { + "displayName": [], + "type": 4 + } + }, + { + "label": "netuid", + "type": { + "displayName": [ + "u16" + ], + "type": 6 + } + } + ], + "default": false, + "docs": [], + "label": "get_coldkey_lock", + "mutates": false, + "payable": false, + "returnType": { + "displayName": [ + "ink", + "MessageResult" + ], + "type": 25 + }, + "selector": "0x29513d8d" + }, + { + "args": [ + { + "label": "coldkey", + "type": { + "displayName": [], + "type": 4 + } + }, + { + "label": "netuid", + "type": { + "displayName": [ + "u16" + ], + "type": 6 + } + } + ], + "default": false, + "docs": [], + "label": "get_stake_availability", + "mutates": false, + "payable": false, + "returnType": { + "displayName": [ + "ink", + "MessageResult" + ], + "type": 30 + }, + "selector": "0xdb1d3b2c" } ] }, @@ -2153,6 +2245,394 @@ }, { "id": 22, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 23 + } + ], + "index": 0, + "name": "Ok" + }, + { + "fields": [ + { + "type": 3 + } + ], + "index": 1, + "name": "Err" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 23 + }, + { + "name": "E", + "type": 3 + } + ], + "path": [ + "Result" + ] + } + }, + { + "id": 23, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 24 + } + ], + "index": 0, + "name": "Ok" + }, + { + "fields": [ + { + "type": 16 + } + ], + "index": 1, + "name": "Err" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 24 + }, + { + "name": "E", + "type": 16 + } + ], + "path": [ + "Result" + ] + } + }, + { + "id": 24, + "type": { + "def": { + "composite": { + "fields": [ + { + "name": "netuid", + "type": 6, + "typeName": "u16" + }, + { + "name": "exists", + "type": 15, + "typeName": "bool" + }, + { + "name": "registered_subnet_counter", + "type": 14, + "typeName": "u64" + } + ] + } + }, + "path": [ + "bittensor", + "SubnetRegistrationState" + ] + } + }, + { + "id": 25, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 26 + } + ], + "index": 0, + "name": "Ok" + }, + { + "fields": [ + { + "type": 3 + } + ], + "index": 1, + "name": "Err" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 26 + }, + { + "name": "E", + "type": 3 + } + ], + "path": [ + "Result" + ] + } + }, + { + "id": 26, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 27 + } + ], + "index": 0, + "name": "Ok" + }, + { + "fields": [ + { + "type": 16 + } + ], + "index": 1, + "name": "Err" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 27 + }, + { + "name": "E", + "type": 16 + } + ], + "path": [ + "Result" + ] + } + }, + { + "id": 27, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 0, + "name": "None" + }, + { + "fields": [ + { + "type": 28 + } + ], + "index": 1, + "name": "Some" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 28 + } + ], + "path": [ + "Option" + ] + } + }, + { + "id": 28, + "type": { + "def": { + "composite": { + "fields": [ + { + "name": "locked_mass", + "type": 14, + "typeName": "u64" + }, + { + "name": "conviction_bits", + "type": 29, + "typeName": "u128" + }, + { + "name": "last_update", + "type": 14, + "typeName": "u64" + } + ] + } + }, + "path": [ + "bittensor", + "ColdkeyLock" + ] + } + }, + { + "id": 29, + "type": { + "def": { + "primitive": "u128" + } + } + }, + { + "id": 30, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 31 + } + ], + "index": 0, + "name": "Ok" + }, + { + "fields": [ + { + "type": 3 + } + ], + "index": 1, + "name": "Err" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 31 + }, + { + "name": "E", + "type": 3 + } + ], + "path": [ + "Result" + ] + } + }, + { + "id": 31, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 32 + } + ], + "index": 0, + "name": "Ok" + }, + { + "fields": [ + { + "type": 16 + } + ], + "index": 1, + "name": "Err" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 32 + }, + { + "name": "E", + "type": 16 + } + ], + "path": [ + "Result" + ] + } + }, + { + "id": 32, + "type": { + "def": { + "composite": { + "fields": [ + { + "name": "netuid", + "type": 6, + "typeName": "u16" + }, + { + "name": "total", + "type": 14, + "typeName": "u64" + }, + { + "name": "locked", + "type": 14, + "typeName": "u64" + }, + { + "name": "available", + "type": 14, + "typeName": "u64" + } + ] + } + }, + "path": [ + "bittensor", + "StakeAvailability" + ] + } + }, + { + "id": 33, "type": { "def": { "composite": { @@ -2172,7 +2652,7 @@ } }, { - "id": 23, + "id": 34, "type": { "def": { "primitive": "u32" @@ -2180,7 +2660,7 @@ } }, { - "id": 24, + "id": 35, "type": { "def": { "variant": {} diff --git a/ts-tests/ink/bittensor.wasm b/ts-tests/ink/bittensor.wasm index 5d54ecf3d6..89e8b81c05 100644 Binary files a/ts-tests/ink/bittensor.wasm and b/ts-tests/ink/bittensor.wasm differ diff --git a/ts-tests/suites/zombienet_evm/00-evm-substrate-transfer.test.ts b/ts-tests/suites/zombienet_evm/00-evm-substrate-transfer.test.ts index 93e245d276..a21b61c777 100644 --- a/ts-tests/suites/zombienet_evm/00-evm-substrate-transfer.test.ts +++ b/ts-tests/suites/zombienet_evm/00-evm-substrate-transfer.test.ts @@ -224,7 +224,7 @@ describeSuite({ authorization_list: [], }); - await waitForTransactionWithRetry(api, tx, signer, "evm_call", 5); + await waitForTransactionWithRetry(api, tx, signer, "evm_call"); const receiverBalanceAfterCall = await getEthBalance(provider, ethWallet.address); expect(receiverBalanceAfterCall).toEqual(receiverBalance + raoToEth(tao(1))); @@ -242,6 +242,7 @@ describeSuite({ ); const contract = await contractFactory.deploy(); await contract.waitForDeployment(); + await waitForFinalizedBlocks(api, 1); const contractAddress = contract.target.toString(); const code = await provider.getCode(contractAddress); @@ -254,6 +255,7 @@ describeSuite({ }; const fundReceipt = await (await ethWallet.sendTransaction(ethTransfer)).wait(); expect(fundReceipt?.status).toEqual(1); + await waitForFinalizedBlocks(api, 1); const contractBalance = await getEthBalance(provider, contractAddress); const callerBalance = await getEthBalance(provider, ethWallet.address); diff --git a/ts-tests/suites/zombienet_evm/03-wasm-contract.test.ts b/ts-tests/suites/zombienet_evm/03-wasm-contract.test.ts index e7e567f87d..a1c0154403 100644 --- a/ts-tests/suites/zombienet_evm/03-wasm-contract.test.ts +++ b/ts-tests/suites/zombienet_evm/03-wasm-contract.test.ts @@ -1213,5 +1213,142 @@ describeSuite({ expect(alphaOutAfter > alphaOutBefore).toBeTruthy(); }, }); + + it({ + id: "T36", + title: "Can get subnet registration state", + test: async () => { + const queryMessage = inkClient.message("get_subnet_registration_state"); + + const data = queryMessage.encode({ + netuid: netuid, + }); + + const response = await api.apis.ContractsApi.call( + convertPublicKeyToSs58(hotkey.publicKey), + contractAddress, + BigInt(0), + undefined, + undefined, + Binary.fromBytes(data.asBytes()) + ); + + expect(response.result.success).toBeTruthy(); + const result = queryMessage.decode(response.result.value).value.value; + if ( + typeof result === "object" && + "netuid" in result && + "exists" in result && + "registered_subnet_counter" in result + ) { + expect(result.netuid).toEqual(netuid); + expect(result.registered_subnet_counter).toBeGreaterThanOrEqual(BigInt(0)); + expect(result.exists).toEqual(true); + } else { + throw new Error("result is not an object"); + } + }, + }); + + it({ + id: "T37", + title: "Can get coldkey lock", + test: async () => { + const queryMessage = inkClient.message("get_coldkey_lock"); + const queryArgs = { + coldkey: Binary.fromBytes(coldkey.publicKey), + netuid: netuid, + }; + + async function queryColdkeyLock() { + const data = queryMessage.encode(queryArgs); + const response = await api.apis.ContractsApi.call( + convertPublicKeyToSs58(hotkey.publicKey), + contractAddress, + BigInt(0), + undefined, + undefined, + Binary.fromBytes(data.asBytes()) + ); + expect(response.result.success).toBeTruthy(); + return queryMessage.decode(response.result.value).value.value as + | { + locked_mass: bigint; + conviction_bits: bigint; + last_update: bigint; + } + | undefined; + } + + let lock = await queryColdkeyLock(); + if (!lock) { + await addStakeViaContract(false); + + const lockAmount = tao(1); + const lockTx = api.tx.SubtensorModule.lock_stake({ + hotkey: convertPublicKeyToSs58(hotkey.publicKey), + netuid: netuid, + amount: lockAmount, + }); + await waitForTransactionWithRetry(api, lockTx, coldkey, "lock_stake"); + + lock = await queryColdkeyLock(); + } + + expect(lock).toBeDefined(); + + if ( + typeof lock === "object" && + "locked_mass" in lock && + "conviction_bits" in lock && + "last_update" in lock + ) { + expect(lock.locked_mass).toBeGreaterThanOrEqual(BigInt(0)); + expect(lock.conviction_bits).toBeGreaterThanOrEqual(BigInt(0)); + expect(lock.last_update).toBeGreaterThanOrEqual(BigInt(0)); + } else { + throw new Error("result is not an object"); + } + }, + }); + + it({ + id: "T38", + title: "Can get stake availability", + test: async () => { + const queryMessage = inkClient.message("get_stake_availability"); + + const data = queryMessage.encode({ + coldkey: Binary.fromBytes(coldkey.publicKey), + netuid: netuid, + }); + + const response = await api.apis.ContractsApi.call( + convertPublicKeyToSs58(hotkey.publicKey), + contractAddress, + BigInt(0), + undefined, + undefined, + Binary.fromBytes(data.asBytes()) + ); + + expect(response.result.success).toBeTruthy(); + const result = queryMessage.decode(response.result.value).value.value; + if ( + typeof result === "object" && + "netuid" in result && + "locked" in result && + "available" in result && + "total" in result + ) { + expect(result.netuid).toEqual(netuid); + expect(result.locked).toBeGreaterThanOrEqual(BigInt(0)); + expect(result.available).toBeGreaterThanOrEqual(BigInt(0)); + expect(result.total).toBeGreaterThanOrEqual(BigInt(0)); + } else { + throw new Error("result is not an object"); + } + }, + }); }, });