internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: ocadotechnology/aimmo

Issue:
Socket error: address already in use
When running AI:MMO locally, as soon as the main page is loaded, the following error appears in the console. It looks like two workers try to connect to the same port. After this error, the game is executed normally.

`Traceback (most recent call last):
  File "service.py", line 44, in <module>
    run(host=sys.argv[1], port=int(sys.argv[2]), directory=sys.argv[3])
  File "service.py", line 41, in run
    app.run(host, port)
  File "/home/ramon/.local/lib/python2.7/site-packages/flask/app.py", line 841, in run
    run_simple(host, port, self, **options)
  File "/home/ramon/.local/lib/python2.7/site-packages/werkzeug/serving.py", line 739, in run_simple
    inner()
  File "/home/ramon/.local/lib/python2.7/site-packages/werkzeug/serving.py", line 699, in inner
    fd=fd)
  File "/home/ramon/.local/lib/python2.7/site-packages/werkzeug/serving.py", line 593, in make_server
    passthrough_errors, ssl_context, fd=fd)
  File "/home/ramon/.local/lib/python2.7/site-packages/werkzeug/serving.py", line 504, in __init__
    HTTPServer.__init__(self, (host, int(port)), handler)
  File "/usr/lib/python2.7/SocketServer.py", line 417, in __init__
    self.server_bind()
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 108, in server_bind
    SocketServer.TCPServer.server_bind(self)
  File "/usr/lib/python2.7/SocketServer.py", line 431, in server_bind
    self.socket.bind(self.server_address)
  File "/usr/lib/python2.7/socket.py", line 228, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 98] Address already in use
`


Discussion:
I think I fixed the issue, but I will wait for the unity branch to get merged with master before making a pull request.

Resolving patch:
diff --git a/aimmo-game/simulation/worker_manager.py b/aimmo-game/simulation/worker_manager.py
--- a/aimmo-game/simulation/worker_manager.py
+++ b/aimmo-game/simulation/worker_manager.py
@@ -173,7 +173,7 @@ class LocalWorkerManager(WorkerManager):
 
     def __init__(self, *args, **kwargs):
         self.workers = {}
-        self.port_counter = itertools.count(1989)
+        self.port_counter = itertools.count(self.port + 10)
         super(LocalWorkerManager, self).__init__(*args, **kwargs)
 
     def create_worker(self, player_id):


Test patch:
Repository: ocadotechnology/aimmo

Issue:
Minimum Product: Irrelevant MapFeature enum elements and their uses
Remove the irrelevant `MapFeature` elements in `world_state.py` and their uses throughout the codebase.


Discussion:

Resolving patch:
diff --git a/aimmo-game/simulation/state/world_state.py b/aimmo-game/simulation/state/world_state.py
--- a/aimmo-game/simulation/state/world_state.py
+++ b/aimmo-game/simulation/state/world_state.py
@@ -1,12 +1,12 @@
 from enum import Enum
 from collections import defaultdict
 
+
 class MapFeature(Enum):
-    HEALTH_POINT = 'health_point'
-    SCORE_POINT = 'score_point'
     PICKUP = 'pickup'
     OBSTACLE = 'obstacle'
 
+
 class WorldState():
     """
     The world updates class serves as a buffer between the updates generated
@@ -114,9 +114,6 @@ def map_feature_dict(map_feature):
                 # Cell is an obstacle.
                 if not cell.habitable:
                     self.create_map_feature(MapFeature.OBSTACLE.value, map_feature_dict(cell))
-                # Cell is a score point.
-                if cell.generates_score:
-                    self.create_map_feature(MapFeature.SCORE_POINT.value, map_feature_dict(cell))
 
             # Updates.
             for cell in avatar_view.cells_in_view:
@@ -133,6 +130,3 @@ def map_feature_dict(map_feature):
                 # Cell is an obstacle.
                 if not cell.habitable:
                     self.delete_map_feature(MapFeature.OBSTACLE.value, map_feature_dict(cell))
-                # Cell is a score point.
-                if cell.generates_score:
-                    self.delete_map_feature(MapFeature.SCORE_POINT.value, map_feature_dict(cell))


Test patch:
diff --git a/aimmo-game/tests/test_service.py b/aimmo-game/tests/test_service.py
--- a/aimmo-game/tests/test_service.py
+++ b/aimmo-game/tests/test_service.py
@@ -49,7 +49,7 @@ def setup_world(self):
             ],
         ]
         grid = {Location(x, y-1): MockCell(Location(x, y-1), **CELLS[x][y])
-                for y in xrange(3) for x in xrange(2)}
+                for y in range(3) for x in range(2)}
         state_provider.set_world(GameState(WorldMap(grid, {}), avatar_manager))
 
         world_state = WorldState(state_provider)
@@ -67,11 +67,6 @@ def test_player_dict(self):
         self.assertEqual(details['health'], 5)
         self.assertEqual(details['score'], 0)
 
-    def test_score_locations(self):
-        result = self.setup_world()['map_features']['score_point']['create']
-        self.assertEqual(result[0]['x'], 0)
-        self.assertEqual(result[0]['y'], 1)
-
     @skip("not implemented")
     def test_pickup_list(self):
         result = self.setup_world()['map_features']['pickup']['create']
Repository: ocadotechnology/aimmo

Issue:
Game Creator RC initialised with wrong game API URL
The `REPLACE_ME` change in one of the latest PR's has broken the game on minikube level in `minikube.py`.  The URL is incorrect so minikube does not work and prohibits testing. 




Discussion:

Resolving patch:
diff --git a/aimmo_runner/shell_api.py b/aimmo_runner/shell_api.py
--- a/aimmo_runner/shell_api.py
+++ b/aimmo_runner/shell_api.py
@@ -15,6 +15,7 @@
 MINIKUBE = os.path.join(TEST_BIN, 'minikube%s' % FILE_SUFFIX)
 FNULL = open(os.devnull, 'w')
 
+
 def log(message):
     sys.stderr.write(message + "\n")
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -26,6 +26,10 @@
     tests_require=[
         'django-setuptest',
         'httmock',
+        'mock == 2.0.0',
+        'docker == 2.7.0',
+        'kubernetes == 4.0.0',
+        'PyYAML == 3.12',
     ],
     test_suite='setuptest.setuptest.SetupTestSuite',
     version=versioneer.get_version(),


Test patch:
diff --git a/aimmo-game-creator/tests/test_aimmo_game_creator_yaml.py b/aimmo-game-creator/tests/test_aimmo_game_creator_yaml.py
new file mode 100644
--- /dev/null
+++ b/aimmo-game-creator/tests/test_aimmo_game_creator_yaml.py
@@ -0,0 +1,23 @@
+import logging
+from unittest import TestCase
+
+import yaml
+
+logging.basicConfig(level=logging.WARNING)
+
+
+class TestAimmoGameCreatorYaml(TestCase):
+
+    def setUp(self):
+        with open("rc-aimmo-game-creator.yaml", 'r') as stream:
+            try:
+                self.yaml_dict = yaml.load(stream)
+            except yaml.YAMLError as exc:
+                logging.debug(exc)
+
+    def test_REPLACE_ME_string_exists(self):
+        """
+        Ensures the yaml template contains the correct string to be replaced.
+        """
+        self.assertEqual(self.yaml_dict['spec']['template']['spec']['containers'][0]['env'][1]['value'],
+                         "REPLACE_ME/api/games")
diff --git a/aimmo_runner/tests/__init__.py b/aimmo_runner/tests/__init__.py
new file mode 100644
diff --git a/aimmo_runner/tests/test_minikube_runner.py b/aimmo_runner/tests/test_minikube_runner.py
new file mode 100644
--- /dev/null
+++ b/aimmo_runner/tests/test_minikube_runner.py
@@ -0,0 +1,19 @@
+import logging
+import mock
+from unittest import TestCase
+from aimmo_runner.minikube import create_creator_yaml
+
+logging.basicConfig(level=logging.WARNING)
+
+
+class TestMinikubeRunner(TestCase):
+
+    @mock.patch('aimmo_runner.minikube.get_ip', return_value='127.0.0.1')
+    def test_game_creator_function_creates_correct_game_url(self, mocked_get_ip_func):
+        """
+        Checks if the game creator yaml is created with the correct game API URL. Relies on get_ip()
+        which we expect to fall back to localhost always.
+        """
+        created_yaml = create_creator_yaml()
+        self.assertEqual(created_yaml['spec']['template']['spec']['containers'][0]['env'][1]['value'],
+                         'http://127.0.0.1:8000/players/api/games')
Repository: ocadotechnology/aimmo

Issue:
Make logout button on AI:MMO



Discussion:

Resolving patch:
diff --git a/players/urls.py b/players/urls.py
--- a/players/urls.py
+++ b/players/urls.py
@@ -10,6 +10,8 @@
     url(r'^$', TemplateView.as_view(template_name='players/home.html'), name='aimmo/home'),
 
     url(r'^accounts/login/$', auth_views.login),
+    url(r'^accounts/logout/$', auth_views.logout, {'next_page' : 'aimmo/logout_success'}, name='aimmo/logout'),
+    url(r'^accounts/logout_success/$', TemplateView.as_view(template_name='registration/success_logout.html'), name='aimmo/logout_success'),
 
     url(r'^program/(?P<id>[0-9]+)/$', login_required(views.ProgramView.as_view()), name='aimmo/program'),
     url(r'^program_level/(?P<num>[0-9]+)/$', login_required(views.program_level), name='aimmo/program_level'),


Test patch:
Repository: ocadotechnology/aimmo

Issue:
Latest minikube not starting on Travis CI
Same issue and hopefully fix as this https://github.com/kubernetes/minikube/issues/2704


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -28,7 +28,7 @@
         'httmock',
         'mock == 2.0.0',
         'docker == 2.7.0',
-        'kubernetes == 4.0.0',
+        'kubernetes == 5.0.0',
         'PyYAML == 3.12',
     ],
     test_suite='setuptest.setuptest.SetupTestSuite',


Test patch:
Repository: NVIDIA/NVFlare

Issue:
CIFAR10 run_fl.py misses license header
https://github.com/NVIDIA/NVFlare/blob/d784e7be9742b4d1bcfa0f389ea063fec984fe50/examples/cifar10/run_fl.py#L1


Discussion:

Resolving patch:
diff --git a/examples/cifar10/run_fl.py b/examples/cifar10/run_fl.py
--- a/examples/cifar10/run_fl.py
+++ b/examples/cifar10/run_fl.py
@@ -1,3 +1,17 @@
+# Copyright (c) 2021, NVIDIA CORPORATION.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 import argparse
 import os
 import time


Test patch:
Repository: NVIDIA/NVFlare

Issue:
Missing config_validator option in provisioning tool
Provisioning tool needs to have config_validator option so the generated fed_server.json can have that information.


Discussion:

Resolving patch:
diff --git a/nvflare/lighter/impl/static_file.py b/nvflare/lighter/impl/static_file.py
--- a/nvflare/lighter/impl/static_file.py
+++ b/nvflare/lighter/impl/static_file.py
@@ -20,10 +20,11 @@
 
 
 class StaticFileBuilder(Builder):
-    def __init__(self, enable_byoc=False, config_folder="", docker_image=""):
+    def __init__(self, enable_byoc=False, config_folder="", app_validator="", docker_image=""):
         self.enable_byoc = enable_byoc
         self.config_folder = config_folder
         self.docker_image = docker_image
+        self.app_validator = app_validator
 
     def _write(self, file_full_path, content, mode, exe=False):
         mode = mode + "w"
@@ -46,6 +47,8 @@ def _build_server(self, server, ctx):
         server_0["admin_host"] = server.name
         server_0["admin_port"] = admin_port
         config["enable_byoc"] = server.enable_byoc
+        if self.app_validator:
+            config["app_validator"] = {"path": self.app_validator}
         self._write(os.path.join(dest_dir, "fed_server.json"), json.dumps(config), "t")
         replacement_dict = {
             "admin_port": admin_port,


Test patch:
Repository: NVIDIA/NVFlare

Issue:
shell scripts missing x permission in poc
The shell script files generated from poc command do not have original permission settings, especially the execute permission, after switching to shutil.unpack_archive.


Discussion:

Resolving patch:
diff --git a/nvflare/__init__.py b/nvflare/__init__.py
--- a/nvflare/__init__.py
+++ b/nvflare/__init__.py
@@ -12,4 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-__version__ = "2.0.5"
+__version__ = "2.0.7"
diff --git a/nvflare/lighter/poc.py b/nvflare/lighter/poc.py
--- a/nvflare/lighter/poc.py
+++ b/nvflare/lighter/poc.py
@@ -44,8 +44,13 @@ def main():
     poc_zip_path = file_dir_path.parent / "poc.zip"
     answer = input("This will delete poc folder in current directory and create a new one. Is it OK to proceed? (y/N) ")
     if answer.strip().upper() == "Y":
-        shutil.rmtree(os.path.join(os.getcwd(), "poc"), ignore_errors=True)
+        dest_poc_folder = os.path.join(os.getcwd(), "poc")
+        shutil.rmtree(dest_poc_folder, ignore_errors=True)
         shutil.unpack_archive(poc_zip_path)
+        for root, dirs, files in os.walk(dest_poc_folder):
+            for file in files:
+                if file.endswith(".sh"):
+                    os.chmod(os.path.join(root, file), 0o755)
         clone_client(args.num_clients)
         print("Successfully creating poc folder.  Please read poc/Readme.rst for user guide.")
 
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -27,7 +27,7 @@
 with open(os.path.join(this_directory, "nvflare", "__init__.py"), encoding="utf-8") as f:
     for line in f.readlines():
         if "__version__" in line:
-            init_version = line.split("=")[1].strip()
+            init_version = line.split("=")[1].strip().strip('"')
 
 nvfl_version = os.environ.get("NVFL_VERSION", init_version)
 yymmdd = datetime.today().strftime("%y%m%d")


Test patch:
Repository: NVIDIA/NVFlare

Issue:
The "show_stats" command got broken
The "show_stats server" and "show_stats client" command got the following error. This is caused by this PR change (https://github.com/NVIDIA/NVFlare/pull/162):

> show_stats server
Error: Failed to communicate with Admin Server localhost on 8003: '_DefaultReplyProcessor' object has no attribute 'process_dict'
Done [7269 usecs] 2022-02-08 17:26:12.865006
> 



Discussion:

Resolving patch:
diff --git a/nvflare/fuel/hci/client/api_spec.py b/nvflare/fuel/hci/client/api_spec.py
--- a/nvflare/fuel/hci/client/api_spec.py
+++ b/nvflare/fuel/hci/client/api_spec.py
@@ -38,6 +38,9 @@ def process_error(self, api: AdminAPISpec, err: str):
     def process_table(self, api: AdminAPISpec, table: Table):
         pass
 
+    def process_dict(self, api: AdminAPISpec, data: dict):
+        pass
+
     def process_shutdown(self, api: AdminAPISpec, msg: str):
         pass
 


Test patch:
Repository: NVIDIA/NVFlare

Issue:
Clients don't shut down
Using admin API with

```
    runner.run(run_number, args.app, restart_all_first=False, shutdown_on_error=True, shutdown_at_end=True,
               timeout=7200, min_clients=args.min_clients)
```
clients don't shut down after end of run.

Similarly when using the admin client console.

Issue was probably introduced with this change https://github.com/NVIDIA/NVFlare/pull/174/files#diff-08f576a2965a40b523edfef473ea838f2a28c0bbce28a1c0bf7015e42dade1c8L345


Discussion:

Resolving patch:
diff --git a/nvflare/private/fed/server/training_cmds.py b/nvflare/private/fed/server/training_cmds.py
--- a/nvflare/private/fed/server/training_cmds.py
+++ b/nvflare/private/fed/server/training_cmds.py
@@ -459,13 +459,13 @@ def _shutdown_app_on_clients(self, conn: Connection) -> bool:
             conn.append_error("no clients to shutdown")
             return False
 
+        replies = self.send_request_to_clients(conn, message)
+        self.process_replies_to_table(conn, replies)
+
         err = engine.remove_clients(clients)
         if err:
             conn.append_error(err)
             return False
-
-        replies = self.send_request_to_clients(conn, message)
-        self.process_replies_to_table(conn, replies)
         return True
 
     def shutdown(self, conn: Connection, args: List[str]):


Test patch:
Repository: NVIDIA/NVFlare

Issue:
Startup folder not configured correctly
I think the `app_root="startup"` should be `app_root=startup` [here](https://github.com/NVIDIA/NVFlare/blob/fa20e5e27b01e0f66cbefea229aed2cf6729663d/nvflare/private/fed/app/server/server_train.py#L67-L69)

If you like I can submit a PR?


Discussion:
Thanks for the issue.

I think you are right, can you submit a PR to change this?

Resolving patch:
diff --git a/nvflare/private/fed/app/server/server_train.py b/nvflare/private/fed/app/server/server_train.py
--- a/nvflare/private/fed/app/server/server_train.py
+++ b/nvflare/private/fed/app/server/server_train.py
@@ -66,7 +66,7 @@ def main():
         # trainer = WorkFlowFactory().create_server_trainer(train_configs, envs)
         startup = os.path.join(args.workspace, "startup")
         conf = FLServerStarterConfiger(
-            app_root="startup",
+            app_root=startup,
             # wf_config_file_name="config_train.json",
             server_config_file_name=args.fed_server,
             # env_config_file_name="environment.json",


Test patch:
Repository: NVIDIA/NVFlare

Issue:
HE aggregator has wrong check for data kind
This [block](https://github.com/NVIDIA/NVFlare/blob/52fa8fc989811526c50ecd4030cc89141b1b26cd/nvflare/app_common/homomorphic_encryption/he_intime_accumulate_model_aggregator.py#L104) should be replaced with 

```
        if dxo.data_kind != self.expected_data_kind:
            self.log_error(fl_ctx, "expected {self.expected_data_kind} type DXO only, skipping this shareable.")
            return False
```

_Originally posted by @holgerroth in https://github.com/NVIDIA/NVFlare/discussions/234#discussioncomment-2340297_


Discussion:

Resolving patch:
diff --git a/nvflare/app_common/homomorphic_encryption/he_intime_accumulate_model_aggregator.py b/nvflare/app_common/homomorphic_encryption/he_intime_accumulate_model_aggregator.py
--- a/nvflare/app_common/homomorphic_encryption/he_intime_accumulate_model_aggregator.py
+++ b/nvflare/app_common/homomorphic_encryption/he_intime_accumulate_model_aggregator.py
@@ -101,8 +101,11 @@ def accept(self, shareable: Shareable, fl_ctx: FLContext) -> bool:
             bool to indicate if this shareable is accepted.
         """
         dxo = from_shareable(shareable)
-        if dxo.data_kind != DataKind.WEIGHT_DIFF:
-            self.log_error(fl_ctx, "support WEIGHT_DIFF type DXO only, skipping this shareable.")
+        if dxo.data_kind != self.expected_data_kind:
+            self.log_error(
+                fl_ctx,
+                f"expected {self.expected_data_kind} type DXO only but received {dxo.data_kind}, skipping this shareable.",
+            )
             return False
 
         enc_algo = dxo.get_meta_prop(key=MetaKey.PROCESSED_ALGORITHM, default=None)


Test patch:
Repository: NVIDIA/NVFlare

Issue:
Server admin port still vulnerable to DOS
There are 128 connections allowed where each is limited to  512mb, this leaves 64GB of memory that can be acquired by a mal actor.

There is also still the issue where it is not checking if the socket is closed.

If I understand the idea of that port, the only data sent through it are some json files? I don't think it justifies such a large max size.

---

I think this is a larger problem though. Why is the the socket being accessed directly? There are many similar gotchas need to be considered when programming directly on a TCP socket and there are many libraries that have already done the hard work of solving those problems.

gRPC is an option since its already in your stack, Flask is an option but it doesn't match the use case too well, zeromq is an option


Discussion:
The admin was taken from a different project from the past. We may change to use other communication mechanism in future. 

As to the volume of data, it could be very large, even though examples only show small json files. For example, some users include model weights (> 300MB) in the app to be uploaded. 
@Nintorac , thanks so much for such a thorough review and analysis - we really appreciate it! 

Just to let you know that NVIDIA takes security issues very seriously. We have a dedicated team for this, and you can report any findings directly to them, if you like: https://www.nvidia.com/en-us/security/report-vulnerability/

We are currently working on a fix based on your findings - another PR is coming soon. When the PR is ready, we'll invite you to review. 

We also think your general comment about not directly using TCP but instead using a well-established framework like http/gRPC is a good one. We actually have a plan to do just that in later releases!

We are following industry best practice and company process to address this issue. We will assign a CVE ID and publish a security advisory after the fix is merged.  We'd like to mention your name in the Advisory, let us know your preferred name and if this is okay with you.


Resolving patch:
diff --git a/nvflare/fuel/hci/server/hci.py b/nvflare/fuel/hci/server/hci.py
--- a/nvflare/fuel/hci/server/hci.py
+++ b/nvflare/fuel/hci/server/hci.py
@@ -23,7 +23,7 @@
 
 from .reg import ServerCommandRegister
 
-MAX_ADMIN_CONNECTIONS = 128
+MAX_ADMIN_CONNECTIONS = 16
 
 
 class _MsgHandler(socketserver.BaseRequestHandler):


Test patch:
Repository: NVIDIA/NVFlare

Issue:
Unable to run poc command if nvflare is installed by pip install -e .



Discussion:

Resolving patch:
diff --git a/nvflare/lighter/poc.py b/nvflare/lighter/poc.py
--- a/nvflare/lighter/poc.py
+++ b/nvflare/lighter/poc.py
@@ -42,11 +42,20 @@ def main():
 
     file_dir_path = pathlib.Path(__file__).parent.absolute()
     poc_zip_path = file_dir_path.parent / "poc.zip"
+    poc_folder_path = file_dir_path.parent / "poc"
     answer = input("This will delete poc folder in current directory and create a new one. Is it OK to proceed? (y/N) ")
     if answer.strip().upper() == "Y":
         dest_poc_folder = os.path.join(os.getcwd(), "poc")
         shutil.rmtree(dest_poc_folder, ignore_errors=True)
-        shutil.unpack_archive(poc_zip_path)
+        try:
+            shutil.unpack_archive(poc_zip_path)
+        except shutil.ReadError:
+            print(f"poc.zip not found at {poc_zip_path}, try to use template poc folder")
+            try:
+                shutil.copytree(poc_folder_path, dest_poc_folder)
+            except BaseException:
+                print(f"Unable to copy poc folder from {poc_folder_path}.  Exit")
+                exit(1)
         for root, dirs, files in os.walk(dest_poc_folder):
             for file in files:
                 if file.endswith(".sh"):


Test patch: