Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: basic functions for worker manager #2

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
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
9 changes: 7 additions & 2 deletions worker-manager/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,17 @@ default = []
backtraces = ["cosmwasm-std/backtraces"]

[dependencies]
cosmwasm-std = { git = "https://github.com/scrtlabs/cosmwasm", tag = "v1.1.9-secret" }
cosmwasm-storage = { git = "https://github.com/scrtlabs/cosmwasm", tag = "v1.1.9-secret" }
cosmwasm-std = { package = "secret-cosmwasm-std", version = "1.1.11" }
cosmwasm-storage = { package = "secret-cosmwasm-storage", version = "1.1.11" }
secret-toolkit = { version = "0.10.0", default-features = false, features = [
"storage"
] }
schemars = { version = "0.8.11" }
serde = { version = "1.0" }
thiserror = { version = "1.0" }
cosmwasm-schema = "1.0.0"
sha2 = "0.10.8"
hex = "0.4.3"

# Uncomment these for some common extra tools
# secret-toolkit = { git = "https://github.com/scrtlabs/secret-toolkit", tag = "v0.8.0" }
Expand Down
2 changes: 1 addition & 1 deletion worker-manager/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ build-mainnet-reproducible:

.PHONY: compress-wasm
compress-wasm:
cp ./target/wasm32-unknown-unknown/release/*.wasm ./contract.wasm
cp ./target/wasm32-unknown-unknown/release/claive_worker_manager.wasm ./contract.wasm
@## The following line is not necessary, may work only on linux (extra size optimization)
@# wasm-opt -Os ./contract.wasm -o ./contract.wasm
cat ./contract.wasm | gzip -9 > ./contract.wasm.gz
Expand Down
146 changes: 146 additions & 0 deletions worker-manager/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Worker Manager Smart Contract

This smart contract is designed to manage a list of workers. Each worker is registered with their IP address, payment wallet, and an attestation report. The contract allows administrators and workers to interact with and update worker information, as well as query the current state of registered workers.

## Features

- **Register a Worker**: Allows the registration of a worker with their IP address, payment wallet, and attestation report.
- **Set Worker Wallet**: Allows a worker to update their payment wallet.
- **Set Worker Address**: Allows a worker to update their IP address.
- **Query Workers**: Allows querying of all registered workers.
- **Liveliness Reporting**: A placeholder for liveliness reporting (yet to be implemented).
- **Work Reporting**: A placeholder for work reporting (yet to be implemented).

## Contract Structure

### Messages

- **InstantiateMsg**: Used for instantiating the contract with an administrator.
- **ExecuteMsg**: Used to execute contract actions like registering a worker, setting worker details, etc.
- **QueryMsg**: Used to query the state of the contract, such as fetching workers or liveliness challenges.

### State

The contract stores the state using the following data structures:

- **State**: Holds the admin address.
- **Worker**: Stores a worker's information, such as IP address, payment wallet, and attestation report.
- **WORKERS_MAP**: A mapping that associates a worker's IP address with their information.

## Functions

### `try_register_worker`

Registers a worker by adding their IP address, payment wallet, and attestation report to the storage.

### `try_set_worker_wallet`

Allows a worker to update their payment wallet. It searches for a worker using the sender's address and updates their wallet.

### `try_set_worker_address`

Allows a worker to update their IP address. It searches for a worker using the sender's address and updates their IP address.

### `try_report_liveliness`

A placeholder function for reporting worker liveliness. This feature has yet to be implemented.

### `try_report_work`

A placeholder function for reporting a worker's work. This feature has yet to be implemented.

### `query_workers`

Queries all workers in storage and returns a list of their information.

### `query_liveliness_challenge`

Returns a liveliness challenge (placeholder response). This feature has yet to be implemented.

## How to Deploy

1. **Set up the CosmWasm environment**:
- Install the required tools for working with CosmWasm contracts, such as Rust, Cargo, and CosmWasm CLI.

2. **Compile the Contract**:
- Use `make build` to compile the contract to WebAssembly (Wasm).

3. **Deploy the Contract**:
- Deploy the compiled contract to the Secret Network using the `secretcli` or other relevant tools.

4. **Interact with the Contract**:
- Once deployed, you can interact with the contract using `secretcli` or by sending transactions via the Secret Network REST or gRPC endpoints.

## Example Queries and Transactions

### Register a Worker

To register a worker, execute the `RegisterWorker` action with the required parameters:

```bash
secretcli tx compute exec <contract_address> '{"register_worker":{"ip_address":"192.168.1.1","payment_wallet":"secret1xyz","attestation_report":""}}' --from <your_wallet>
```

### Query Workers

To query all workers, execute the `GetWorkers` query:

```bash
secretcli q compute query <contract_address> '{"get_workers": {"signature":<signed_msg_hex>, "subscriber_public_key":<pub_key_hex>}}'
```

This Python example demonstrates signing a message with your private key and verifying it using the Secret SDK and secp256k1.

```python
from secret_sdk.client.lcd import LCDClient
from secret_sdk.key.mnemonic import MnemonicKey
import secp256k1

chain_id = 'pulsar-3'
node_url = 'https://api.pulsar.scrttestnet.com'
mnemonic = 'grant rice replace explain federal release fix clever romance raise often wild taxi quarter soccer fiber love must tape steak together observe swap guitar'

mk = MnemonicKey(mnemonic=mnemonic)
secret = LCDClient(chain_id=chain_id, url=node_url)
wallet = secret.wallet(mk)

private_key_secp = secp256k1.PrivateKey(bytes.fromhex(mk.private_key.hex()))
message = bytes.fromhex(mk.public_key.key.hex())

signature = private_key_secp.ecdsa_sign(message)
signature_der = private_key_secp.ecdsa_serialize_compact(signature)

print("signature: ", signature_der.hex())

sig = private_key_secp.ecdsa_deserialize_compact(signature_der)

is_valid = private_key_secp.pubkey.ecdsa_verify(message, sig)
print("is_valid: ", is_valid)
```

Expected output:

```bash
pubkey: 034ee8249f67e136139c3ed94ad63288f6c1de45ce66fa883247211a698f440cdf
signature: 164a70762475db7f55b2fa2932ac35f761e27628ca13e9b8512137e256d93ea027ebcbb6725f23b3f720a4e00d5e57cbdc60c785437d943c62efba2bc5f61d85
is_valid: True
```

### Set Worker Wallet

To update a worker's wallet:

```bash
secretcli tx compute exec <contract_address> '{"set_worker_wallet":{"ip_address":"192.168.1.1", "payment_wallet":"secret1newwallet"}}' --from <your_wallet>
```
### Set Worker Address

To update a worker's wallet:

```bash
secretcli tx compute exec <contract_address> '{"set_worker_address": {"new_ip_address": "<new_ip>", "old_ip_address": "<old_ip>>"}}' --from <your_wallet>
```

### Notes

- Liveliness reporting and work reporting are placeholder features and have not been implemented yet.
4 changes: 4 additions & 0 deletions worker-manager/integration-tests/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CHAIN_ID=pulsar-3
CONTRACT_ADDRESS=secret1xy3tf8f80k7czypsn2j29z3jfcxny5x244znv7
NODE_URL=https://api.pulsar.scrttestnet.com
MNEMONIC='grant rice replace explain federal release fix clever romance raise often wild taxi quarter soccer fiber love must tape steak together observe swap guitar'
73 changes: 73 additions & 0 deletions worker-manager/integration-tests/modify_worker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import os
from time import sleep

from dotenv import load_dotenv
from secret_sdk.client.lcd import LCDClient
from secret_sdk.client.localsecret import LocalSecret, main_net_chain_id, test_net_chain_id
from secret_sdk.core.coins import Coins
from secret_sdk.key.mnemonic import MnemonicKey
from secret_sdk.protobuf.cosmos.tx.v1beta1 import BroadcastMode

load_dotenv()
chain_id = os.getenv('CHAIN_ID')
contract = os.getenv('CONTRACT_ADDRESS')
node_url = os.getenv('NODE_URL')
mnemonic = os.getenv('MNEMONIC')

print("chain_id: " + chain_id)
print("node_url: " + node_url)
print("contract: " + contract)
print("mnemonic: " + mnemonic)

mk = MnemonicKey(mnemonic=mnemonic)
secret = LCDClient(chain_id=chain_id, url=node_url)
wallet = secret.wallet(mk)

wallet_public_key = str(wallet.key.acc_address)

print("wallet_public_key: " + wallet_public_key)

contract_address = contract
sent_funds = Coins('100uscrt')

handle_msg = {"set_worker_address": {"new_ip_address": "192.168.0.3", "old_ip_address": "192.168.0.1"}}

t = wallet.execute_tx(
contract_addr=contract_address,
handle_msg=handle_msg,
transfer_amount=sent_funds,
)

print(t)

assert t.code == 0, f"Transaction failed with code {t.code}: {t.rawlog}"
print("Transaction successful:", t.txhash)

sleep(10)

# test set_worker_wallet

tx_info = secret.tx.tx_info(
tx_hash=t.txhash,
)
print("Transaction info:", tx_info)

handle_msg = {"set_worker_wallet": {"payment_wallet": "secret1ap26qrlp8mcq2pg6r47w43l0y8zkqm8a450s07", "ip_address": "192.168.0.3"}}

t = wallet.execute_tx(
contract_addr=contract_address,
handle_msg=handle_msg,
transfer_amount=sent_funds,
)

print(t)

assert t.code == 0, f"Transaction failed with code {t.code}: {t.rawlog}"
print("Transaction successful:", t.txhash)

sleep(10)

tx_info = secret.tx.tx_info(
tx_hash=t.txhash,
)
print("Transaction info:", tx_info)
21 changes: 21 additions & 0 deletions worker-manager/integration-tests/query_list_of_workers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import os

from dotenv import load_dotenv
from secret_sdk.client.lcd import LCDClient

load_dotenv()
chain_id = os.getenv('CHAIN_ID')
contract = os.getenv('CONTRACT_ADDRESS')
node_url = os.getenv('NODE_URL')

print("chain_id: " + chain_id)
print("node_url: " + node_url)
print("contract: " + contract)

secret = LCDClient(chain_id=chain_id, url=node_url)

query = {"get_workers": {"signature": "", "subscriber_public_key": ""}}

result = secret.wasm.contract_query(contract, query)

print(result)
49 changes: 49 additions & 0 deletions worker-manager/integration-tests/register_worker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import os
from time import sleep

from dotenv import load_dotenv
from secret_sdk.client.lcd import LCDClient
from secret_sdk.core.coins import Coins
from secret_sdk.key.mnemonic import MnemonicKey

load_dotenv()
chain_id = os.getenv('CHAIN_ID')
contract = os.getenv('CONTRACT_ADDRESS')
node_url = os.getenv('NODE_URL')
mnemonic = os.getenv('MNEMONIC')

print("chain_id: " + chain_id)
print("node_url: " + node_url)
print("contract: " + contract)
print("mnemonic: " + mnemonic)

mk = MnemonicKey(mnemonic=mnemonic)
secret = LCDClient(chain_id=chain_id, url=node_url)
wallet = secret.wallet(mk)

wallet_public_key = str(wallet.key.acc_address)

print("wallet_public_key: " + wallet_public_key)

contract_address = contract
sent_funds = Coins('10000uscrt')

handle_msg = {"register_worker" : {"ip_address" : "192.0.0.1", "payment_wallet" : wallet_public_key, "attestation_report": ""}}

t = wallet.execute_tx(
contract_addr=contract_address,
handle_msg=handle_msg,
transfer_amount=sent_funds,
)

print(t)

assert t.code == 0, f"Transaction failed with code {t.code}: {t.rawlog}"
print("Transaction successful:", t.txhash)

sleep(10)

tx_info = secret.tx.tx_info(
tx_hash=t.txhash,
)
print("Transaction info:", tx_info)
4 changes: 2 additions & 2 deletions worker-manager/src/bin/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::fs::create_dir_all;
use cosmwasm_schema::{export_schema, remove_schemas, schema_for};

use claive_worker_manager::msg::{
ExecuteMsg, GetLivelinessChallengeResponse, GetNextWorkerResponse, InstantiateMsg, QueryMsg,
ExecuteMsg, GetLivelinessChallengeResponse, GetWorkersResponse, InstantiateMsg, QueryMsg,
};
use claive_worker_manager::state::State;

Expand All @@ -18,6 +18,6 @@ fn main() {
export_schema(&schema_for!(ExecuteMsg), &out_dir);
export_schema(&schema_for!(QueryMsg), &out_dir);
export_schema(&schema_for!(State), &out_dir);
export_schema(&schema_for!(GetNextWorkerResponse), &out_dir);
export_schema(&schema_for!(GetWorkersResponse), &out_dir);
export_schema(&schema_for!(GetLivelinessChallengeResponse), &out_dir);
}
Loading