Skip to content

Commit

Permalink
Merge pull request #24 from cybercongress/template-release
Browse files Browse the repository at this point in the history
Template release
  • Loading branch information
cyborgshead authored Apr 10, 2024
2 parents ddf1535 + f1a1615 commit 7ba848b
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 94 deletions.
12 changes: 1 addition & 11 deletions cybertensor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
nest_asyncio.apply()

# Cybertensor code and protocol version.
__version__ = "0.1.6"
__version__ = "0.2.0"
version_split = __version__.split(".")
__version_as_int__ = (
(100 * int(version_split[0]))
Expand Down Expand Up @@ -65,15 +65,6 @@ def turn_console_on():
turn_console_on()


# Logging helpers.
def trace(on: bool = True):
logging.set_trace(on)


def debug(on: bool = True):
logging.set_debug(on)


class NetworkConfigCwTensor(NetworkConfig):
def __init__(
self,
Expand Down Expand Up @@ -196,7 +187,6 @@ def __init__(
from cybertensor.dendrite import dendrite
from cybertensor.config import Config
from cybertensor.mock import MockCwtensor, MockWallet
# from .subnets import SubnetsAPI

configs = [
axon.config(),
Expand Down
44 changes: 21 additions & 23 deletions cybertensor/axon.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from starlette.responses import Response

import cybertensor
import cybertensor.utils.networking as net
from cybertensor.config import Config
from cybertensor.errors import *
from cybertensor.keypair import Keypair
Expand Down Expand Up @@ -184,7 +185,7 @@ class MySynapse( cybertensor.Synapse ):
output: int = None
# Define a custom request forwarding function
def forward( synapse: MySynapse ) -> MySynapse:
def forward_my_synapse( synapse: MySynapse ) -> MySynapse:
# Apply custom logic to synapse and return it
synapse.output = 2
return synapse
Expand All @@ -194,13 +195,13 @@ def verify_my_synapse( synapse: MySynapse ):
# Apply custom verification logic to synapse
# Optionally raise Exception
# Define a custom request blacklist fucntion
# Define a custom request blacklist function
def blacklist_my_synapse( synapse: MySynapse ) -> bool:
# Apply custom blacklist
# return False ( if non blacklisted ) or True ( if blacklisted )
# Define a custom request priority fucntion
def prioritize_my_synape( synapse: MySynapse ) -> float:
# Define a custom request priority function
def prioritize_my_synapse( synapse: MySynapse ) -> float:
# Apply custom priority
return 1.0
Expand All @@ -212,12 +213,12 @@ def prioritize_my_synape( synapse: MySynapse ) -> float:
forward_fn = forward_my_synapse,
verify_fn = verify_my_synapse,
blacklist_fn = blacklist_my_synapse,
priority_fn = prioritize_my_synape
priority_fn = prioritize_my_synapse
).attach(
forward_fn = forward_my_synapse_2,
verify_fn = verify_my_synapse_2,
blacklist_fn = blacklist_my_synapse_2,
priority_fn = prioritize_my_synape_2
priority_fn = prioritize_my_synapse_2
).serve(
netuid = ...
cwtensor = ...
Expand Down Expand Up @@ -309,16 +310,8 @@ def __init__(
self.uuid = str(uuid.uuid1())
self.ip = self.config.axon.ip
self.port = self.config.axon.port
self.external_ip = (
self.config.axon.external_ip
if self.config.axon.external_ip is not None
else cybertensor.utils.networking.get_external_ip()
)
self.external_port = (
self.config.axon.external_port
if self.config.axon.external_port is not None
else self.config.axon.port
)
self.external_ip = self.config.axon.external_ip or net.get_external_ip()
self.external_port = self.config.axon.external_port or self.config.axon.port
self.full_address = str(self.config.axon.ip) + ":" + str(self.config.axon.port)
self.started = False

Expand Down Expand Up @@ -687,12 +680,12 @@ def check_config(cls, config: "Config"):
Raises:
AssertionError: If the axon or external ports are not in range [1024, 65535]
"""
assert (
config.axon.port > 1024 and config.axon.port < 65535
assert config.axon.port is None or (
1024 < config.axon.port < 65535
), "Axon port must be in range [1024, 65535]"

assert config.axon.external_port is None or (
config.axon.external_port > 1024 and config.axon.external_port < 65535
1024 < config.axon.external_port < 65535
), "External port must be in range [1024, 65535]"

def to_string(self):
Expand Down Expand Up @@ -847,7 +840,10 @@ async def default_verify(self, synapse: cybertensor.Synapse):
"""
# Build the keypair from the dendrite_hotkey
if synapse.dendrite is not None:
keypair = Keypair(address=synapse.dendrite.hotkey) # type: ignore
cybertensor.logging.info(f"dendrite: {synapse.dendrite}")
# NOTE added public key to the synapese for correct keypair initialization
# keypair = Keypair(address=synapse.dendrite.hotkey)
keypair = Keypair(address=synapse.dendrite.hotkey, public_key=synapse.dendrite.pubkey)
# Build the signature messages.
message = (f"{synapse.dendrite.nonce}.{synapse.dendrite.hotkey}.{self.wallet.hotkey.address}."
f"{synapse.dendrite.uuid}.{synapse.computed_body_hash}")
Expand All @@ -864,7 +860,7 @@ async def default_verify(self, synapse: cybertensor.Synapse):
):
raise Exception("Nonce is too small")

if not keypair.verify(message, synapse.dendrite.signature): # type: ignore
if not keypair.verify(message, synapse.dendrite.signature):
raise Exception(
f"Signature mismatch with {message} and {synapse.dendrite.signature}"
)
Expand Down Expand Up @@ -981,11 +977,13 @@ async def dispatch(
# Logs the start of the request processing
if synapse.dendrite is not None:
cybertensor.logging.trace(
f"axon | <-- | {request.headers.get('content-length', -1)} B | {synapse.name} | {synapse.dendrite.hotkey} | {synapse.dendrite.ip}:{synapse.dendrite.port} | 200 | Success "
f"axon | <-- | {request.headers.get('content-length', -1)} B | {synapse.name} | "
f"{synapse.dendrite.hotkey} | {synapse.dendrite.ip}:{synapse.dendrite.port} | 200 | Success "
)
else:
cybertensor.logging.trace(
f"axon | <-- | {request.headers.get('content-length', -1)} B | {synapse.name} | None | None | 200 | Success "
f"axon | <-- | {request.headers.get('content-length', -1)} B | {synapse.name} | "
f"None | None | 200 | Success "
)

# Call the blacklist function
Expand Down
16 changes: 9 additions & 7 deletions cybertensor/contract/schema/execute.json
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,7 @@
],
"properties": {
"ip": {
"type": "integer",
"format": "uint128",
"minimum": 0.0
"$ref": "#/definitions/Uint128"
},
"ip_type": {
"type": "integer",
Expand Down Expand Up @@ -239,9 +237,7 @@
],
"properties": {
"ip": {
"type": "integer",
"format": "uint128",
"minimum": 0.0
"$ref": "#/definitions/Uint128"
},
"ip_type": {
"type": "integer",
Expand Down Expand Up @@ -1449,5 +1445,11 @@
},
"additionalProperties": false
}
]
],
"definitions": {
"Uint128": {
"description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```",
"type": "string"
}
}
}
23 changes: 23 additions & 0 deletions cybertensor/contract/schema/query.json
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,29 @@
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"get_subnetwork_n"
],
"properties": {
"get_subnetwork_n": {
"type": "object",
"required": [
"netuid"
],
"properties": {
"netuid": {
"type": "integer",
"format": "uint16",
"minimum": 0.0
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
Expand Down
37 changes: 24 additions & 13 deletions cybertensor/cwtensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,11 +345,15 @@ def make_call_with_retry(self, wait_for_finalization: bool,
self.contract.execute(msg, signer_wallet, gas, funds=funds)
return True
else:
tx = self.contract.execute(msg, signer_wallet, gas, funds=funds)
try:
# NOTE will raise exception if tx simulation is not successful, need to catch it
tx = self.contract.execute(msg, signer_wallet, gas, funds=funds)
except Exception as e:
raise error(e.__str__())
try:
tx.wait_to_complete()
if tx.response.is_successful():
print(f'Gas used: {tx.response.gas_used}')
cybertensor.logging.trace(f'Gas used: {tx.response.gas_used}')
return True
else:
raise error(tx.response.logs)
Expand All @@ -371,6 +375,7 @@ def _execute_contract(self, wait_for_finalization: bool,
signer_wallet = LocalWallet(
PrivateKey(_private_key), self.address_prefix
)
cybertensor.logging.trace(f'tx msg {msg}\tsigner_wallet {signer_wallet}')
res = self.make_call_with_retry(
wait_for_finalization=wait_for_finalization,
msg=msg,
Expand Down Expand Up @@ -402,11 +407,17 @@ def _execute_contract(self, wait_for_finalization: bool,
def make_call_with_retry_2(self, wait_for_finalization: bool,
msg: dict, signer_wallet: LocalWallet, gas: Optional[int] = cybertensor.__default_gas__,
funds: Optional[str] = None) -> [bool, Optional[str]]:
cybertensor.logging.trace(f'tx msg {msg}\tsigner_wallet {signer_wallet}')
if not wait_for_finalization:
self.contract.execute(msg, signer_wallet, gas, funds=funds)
return True, None
else:
tx = self.contract.execute(msg, signer_wallet, gas, funds=funds)
try:
# NOTE will raise exception if tx simulation is not successful, need to catch it
tx = self.contract.execute(msg, signer_wallet, gas, funds=funds)
except Exception as e:
return False, e.__str__()

try:
tx.wait_to_complete()
if tx.response.is_successful():
Expand All @@ -417,9 +428,9 @@ def make_call_with_retry_2(self, wait_for_finalization: bool,
except Exception as e:
return False, e.__str__()

####################
#### Websocket Interface related
####################
#####################################
#### Websocket Interface related ####
#####################################
def connect_websocket(self):
"""
(Re)creates the websocket connection, if the URL contains a 'ws' or 'wss' scheme
Expand Down Expand Up @@ -1457,9 +1468,9 @@ def root_set_weights(
prompt=prompt,
)

#####################################
#### Hyper parameter calls. ####
#####################################
###############################
#### Hyper parameter calls ####
###############################

def difficulty(self, netuid: int, block: Optional[int] = None) -> Optional[int]:
"""
Expand Down Expand Up @@ -1749,9 +1760,9 @@ def tx_rate_limit(self, block: Optional[int] = None) -> Optional[int]:
"""
return self.contract.query({"get_tx_rate_limit": {}})

#####################################
############################
#### Network Parameters ####
#####################################
############################

def get_subnet_burn_cost(self, block: Optional[int] = None) -> Optional[int]:
lock_cost = self.contract.query({"get_network_registration_cost": {}})
Expand Down Expand Up @@ -2092,9 +2103,9 @@ def get_stake_info_for_coldkeys(

return StakeInfo.list_of_tuple_from_list_any(result)

########################################
#######################################
#### Neuron information per subnet ####
########################################
#######################################

def is_hotkey_registered_any(
self, hotkey: str, block: Optional[int] = None
Expand Down
2 changes: 2 additions & 0 deletions cybertensor/dendrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,13 +620,15 @@ def preprocess_synapse_for_request(
nonce=time.monotonic_ns(),
uuid=self.uuid,
hotkey=self.keypair.address,
pubkey=self.keypair.public_key
)

# Build the Axon headers using the target axon's details
synapse.axon = cybertensor.TerminalInfo(
ip=target_axon_info.ip,
port=target_axon_info.port,
hotkey=target_axon_info.hotkey,
pubkey=None
)

# Sign the request using the dendrite, axon info, and the synapse body hash
Expand Down
8 changes: 7 additions & 1 deletion cybertensor/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,19 @@ class KeyFileError(Exception):
pass


class ConfigurationError(Exception):
r"""Error raised when a private key is not found."""
pass


class MetadataError(ChainTransactionError):
r"""Error raised when metadata commitment transaction fails."""

pass


class InvalidRequestNameError(Exception):
r"""This exception is raised when the request name is invalid. Ususally indicates a broken URL."""
r"""This exception is raised when the request name is invalid. Usually indicates a broken URL."""

pass

Expand Down Expand Up @@ -146,6 +151,7 @@ class PriorityException(Exception):

pass


class PostProcessException(Exception):
r"""This exception is raised when the response headers cannot be updated."""

Expand Down
Loading

0 comments on commit 7ba848b

Please sign in to comment.