Skip to content
Closed
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: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ The graphml file has the following specification:
* `y` specifies the node's y position when rendered in a GUI
* `version` specifies the node's Bitcoin Core major version, or built branch
* `bitcoin_config` is a comma-separated list of values the node should apply to it's bitcoin.conf, using bitcoin.conf syntax
* `profile` is a profile name from the pre-built selection in src/warnet/resources.py

`version` should be either a version number from the pre-compiled binary list on https://bitcoincore.org/bin/ **or** a built branch using `<user>/<repo>#<branch>` syntax.

Expand All @@ -54,6 +55,7 @@ Nodes can be added to the graph as follows:
<data key="version">24.0</data>
<data key="bitcoin_config">uacomment=warnet0_v24,debugexclude=libevent</data>
<data key="tc_netem"></data>
<data key="profile"></data>
</node>
```

Expand All @@ -66,6 +68,7 @@ Or for a custom built branch with traffic shaping rules applied:
<data key="version">vasild/bitcoin#relay_tx_to_priv_nets</data>
<data key="bitcoin_config">uacomment=warnet1_custom,debug=1</data>
<data key="tc_netem">tc qdisc add dev eth0 root netem delay 100ms</data>
<data key="profile">raspberry_pi</data>
</node>
```

Expand Down
5 changes: 5 additions & 0 deletions src/templates/example.graphml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?><graphml xmlns="http://graphml.graphdrawing.org/xmlns">
<key attr.name="version" attr.type="string" for="node" id="version"/>
<key attr.name="bitcoin_config" attr.type="string" for="node" id="bitcoin_config"/>
<key attr.name="tc_netem" attr.type="string" for="node" id="tc_netem"/>
<key attr.name="profile" attr.type="string" for="node" id="profile"/>
<graph edgedefault="directed">
<node id="0">
<data key="version">25.0</data>
Expand All @@ -13,10 +15,13 @@
<node id="2">
<data key="version">23.2</data>
<data key="bitcoin_config">uacomment=w2</data>
<data key="profile">laptop</data>
</node>
<node id="3">
<data key="version">22.1</data>
<data key="bitcoin_config">uacomment=w3</data>
<data key="profile">raspberry_pi</data>
<data key="tc_netem">tc qdisc add dev eth0 root netem delay 1000ms</data>
</node>
<node id="4">
<data key="version">0.21.2</data>
Expand Down
23 changes: 23 additions & 0 deletions src/warnet/resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# resource profile presets
resource_profiles = {
"default": {
"cpus": "4",
"memory": "4G",
},
"raspberry_pi": {
"cpus": "2",
"memory": "2G",
},
"laptop": {
"cpus": "4",
"memory": "8G",
},
"desktop": {
"cpus": "8",
"memory": "16G",
},
"server": {
"cpus": "16",
"memory": "32G",
},
}
22 changes: 20 additions & 2 deletions src/warnet/tank.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
SUPPORTED_TAGS,
get_architecture,
)
from warnet.resources import resource_profiles

CONTAINER_PREFIX_BITCOIND = "tank"
CONTAINER_PREFIX_PROMETHEUS = "prometheus_exporter"
Expand All @@ -35,6 +36,7 @@ def __init__(self):
self.conf_file = None
self.torrc_file = None
self.netem = None
self.resource_profile = None
self.rpc_port = 18443
self.rpc_user = "warnet_user"
self.rpc_password = "2themoon"
Expand All @@ -53,6 +55,7 @@ def __str__(self) -> str:
f"\tConf: {self.conf}\n"
f"\tConf File: {self.conf_file}\n"
f"\tNetem: {self.netem}\n"
f"\tProfile: {self.resource_profile}\n"
f"\tIPv4: {self._ipv4}\n"
f"\t)"
)
Expand All @@ -78,6 +81,13 @@ def from_graph_node(cls, index, warnet):
self.conf = node["bitcoin_config"]
if "tc_netem" in node:
self.netem = node["tc_netem"]
# TODO: updgrade to use docker swarm mode, then we can properly set CPU#'s
if "profile" in node:
if node["profile"] not in resource_profiles:
logger.warning(f"Unknown profile {node['profile']} set for node {self.index}")
else:
self.resource_profile = resource_profiles[node["profile"]]
logger.debug(f"Setting profile {node['profile']} for node {self.index}")
with open(self.warnet.fork_observer_config, "a") as f:
f.write(
f"""
Expand Down Expand Up @@ -160,8 +170,8 @@ def apply_network_conditions(self):
return

# Apply the network condition to the container
rcode, result = self.exec(self.netem)
if rcode == 0:
result = self.container.exec_run(cmd=self.netem, user="root")
if result.exit_code == 0:
logger.info(
f"Successfully applied network conditions to {self.container_name}: `{self.netem}`"
)
Expand Down Expand Up @@ -257,6 +267,14 @@ def add_services(self, services):
# }
}
)
# this could be updated to deploy {CPU, memory} if we use swarm or similar
if self.resource_profile:
services[self.container_name].update(
{
"cpu_shares": int(self.resource_profile.get("cpus", "0.5")) * 1024,
"mem_limit": self.resource_profile.get("memory", "512M"),
}
)

# Add the prometheus data exporter in a neighboring container
services[self.exporter_name] = {
Expand Down
3 changes: 1 addition & 2 deletions src/warnet/warnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,9 @@ def apply_zone_file(self):
content_str = f.read().replace("'", "'\\''")

# Overwrite all existing content
result = seeder.exec_run(
_result = seeder.exec_run(
f"sh -c 'echo \"{content_str}\" > /etc/bind/invalid.zone'"
)
logger.debug(f"result of updating {ZONE_FILE_NAME}: {result}")

# Reload that single zone only
seeder.exec_run("rndc reload invalid")
Expand Down