From df3b79404f66bc02580b1e1881ff589b113f2779 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 4 May 2021 17:04:17 +0200
Subject: [PATCH 001/147] test: skip ganache/oef tests when running in CI
---
.github/workflows/workflow.yml | 4 ++--
tests/common/utils.py | 1 +
tests/conftest.py | 1 +
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml
index db1d24562e..63ecbe4915 100644
--- a/.github/workflows/workflow.yml
+++ b/.github/workflows/workflow.yml
@@ -293,7 +293,7 @@ jobs:
run: |
tox -e py3.8 -- -m 'sync' # --aea-loop sync
- name: Async integration tests
- run: tox -e py3.8 -- -m 'integration and not unstable and not ledger'
+ run: tox -e py3.8 -- -m 'integration and not unstable and not ledger and not skip_in_ci'
integration_checks_ledger:
continue-on-error: True
@@ -349,7 +349,7 @@ jobs:
fetchcli config indent true
fetchcli config broadcast-mode block
- name: Integration tests
- run: tox -e py3.8 -- -m 'integration and not unstable and ledger'
+ run: tox -e py3.8 -- -m 'integration and not unstable and ledger and not skip_in_ci'
platform_checks:
continue-on-error: True
diff --git a/tests/common/utils.py b/tests/common/utils.py
index 30b1720057..ba21020c0b 100644
--- a/tests/common/utils.py
+++ b/tests/common/utils.py
@@ -395,6 +395,7 @@ def run_aea_subprocess(*args, cwd: str = ".") -> Tuple[subprocess.Popen, str, st
return result, stdout.decode("utf-8"), stderr.decode("utf-8")
+@pytest.mark.skip_in_ci
@pytest.mark.integration
class UseOef: # pylint: disable=too-few-public-methods
"""Inherit from this class to launch an OEF node."""
diff --git a/tests/conftest.py b/tests/conftest.py
index 2f94ad344d..0a0387aa47 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1402,6 +1402,7 @@ def make_uri(addr: str, port: int):
return f"{addr}:{port}"
+@pytest.mark.skip_in_ci
@pytest.mark.integration
class UseGanache:
"""Inherit from this class to use Ganache."""
From 4e9f3434369dafb8d7363568a4c165be83e21408 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 4 May 2021 17:47:59 +0200
Subject: [PATCH 002/147] test: skip tests if they use OEF or Ganache
Update the 'check_skip' method of the utility test class 'DockerImage'
such that the pytest test is skipped if:
- docker is not available in the OS system path
- docker --version fails
- the version is greater than 19.0.0 (e.g. the default on ubuntu 20.04)
---
.github/workflows/workflow.yml | 4 +--
.../aea-ledger-ethereum/tests/docker_image.py | 33 ++++++++++++++++++-
tests/common/docker_image.py | 31 +++++++++++++++++
tests/common/utils.py | 1 -
tests/conftest.py | 1 -
5 files changed, 65 insertions(+), 5 deletions(-)
diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml
index 63ecbe4915..db1d24562e 100644
--- a/.github/workflows/workflow.yml
+++ b/.github/workflows/workflow.yml
@@ -293,7 +293,7 @@ jobs:
run: |
tox -e py3.8 -- -m 'sync' # --aea-loop sync
- name: Async integration tests
- run: tox -e py3.8 -- -m 'integration and not unstable and not ledger and not skip_in_ci'
+ run: tox -e py3.8 -- -m 'integration and not unstable and not ledger'
integration_checks_ledger:
continue-on-error: True
@@ -349,7 +349,7 @@ jobs:
fetchcli config indent true
fetchcli config broadcast-mode block
- name: Integration tests
- run: tox -e py3.8 -- -m 'integration and not unstable and ledger and not skip_in_ci'
+ run: tox -e py3.8 -- -m 'integration and not unstable and ledger'
platform_checks:
continue-on-error: True
diff --git a/plugins/aea-ledger-ethereum/tests/docker_image.py b/plugins/aea-ledger-ethereum/tests/docker_image.py
index 2d5ade1314..ce8f63538d 100644
--- a/plugins/aea-ledger-ethereum/tests/docker_image.py
+++ b/plugins/aea-ledger-ethereum/tests/docker_image.py
@@ -19,11 +19,15 @@
"""This module contains testing utilities."""
import logging
+import re
+import shutil
+import subprocess
import time
from abc import ABC, abstractmethod
from typing import Dict, List, Optional
import docker
+import pytest
import requests
from docker import DockerClient
from docker.models.containers import Container
@@ -35,7 +39,9 @@
class DockerImage(ABC):
- """A class to wrap interaction with a Docker image."""
+ """A class to wrap interatction with a Docker image."""
+
+ MINIMUM_DOCKER_VERSION = (19, 0, 0)
def __init__(self, client: docker.DockerClient):
"""Initialize."""
@@ -47,6 +53,31 @@ def check_skip(self):
By default, nothing happens.
"""
+ self._check_docker_binary_available()
+
+ def _check_docker_binary_available(self):
+ """Check the 'Docker' CLI tool is in the OS PATH."""
+ result = shutil.which("docker")
+ if result is None:
+ pytest.skip("Docker not in the OS Path; skipping the test")
+
+ result = subprocess.run( # nosec
+ ["docker", "--version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
+ )
+ if result.returncode != 0:
+ pytest.skip(f"'docker --version' failed with exit code {result.returncode}")
+
+ match = re.search(
+ r"Docker version ([0-9]+)\.([0-9]+)\.([0-9]+)",
+ result.stdout.decode("utf-8"),
+ )
+ if match is None:
+ pytest.skip(f"cannot read version from the output of 'docker --version'")
+ version = (int(match.group(1)), int(match.group(2)), int(match.group(3)))
+ if version < self.MINIMUM_DOCKER_VERSION:
+ pytest.skip(
+ f"expected Docker version to be at least {'.'.join(self.MINIMUM_DOCKER_VERSION)}, found {'.'.join(version)}"
+ )
@property
@abstractmethod
diff --git a/tests/common/docker_image.py b/tests/common/docker_image.py
index 77d8b0a835..7e08bb5bd6 100644
--- a/tests/common/docker_image.py
+++ b/tests/common/docker_image.py
@@ -21,6 +21,9 @@
import asyncio
import logging
import os
+import re
+import shutil
+import subprocess # nosec
import sys
import tempfile
import time
@@ -45,6 +48,8 @@
class DockerImage(ABC):
"""A class to wrap interatction with a Docker image."""
+ MINIMUM_DOCKER_VERSION = (19, 0, 0)
+
def __init__(self, client: docker.DockerClient):
"""Initialize."""
self._client = client
@@ -55,6 +60,31 @@ def check_skip(self):
By default, nothing happens.
"""
+ self._check_docker_binary_available()
+
+ def _check_docker_binary_available(self):
+ """Check the 'Docker' CLI tool is in the OS PATH."""
+ result = shutil.which("docker")
+ if result is None:
+ pytest.skip("Docker not in the OS Path; skipping the test")
+
+ result = subprocess.run( # nosec
+ ["docker", "--version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
+ )
+ if result.returncode != 0:
+ pytest.skip(f"'docker --version' failed with exit code {result.returncode}")
+
+ match = re.search(
+ r"Docker version ([0-9]+)\.([0-9]+)\.([0-9]+)",
+ result.stdout.decode("utf-8"),
+ )
+ if match is None:
+ pytest.skip(f"cannot read version from the output of 'docker --version'")
+ version = (int(match.group(1)), int(match.group(2)), int(match.group(3)))
+ if version < self.MINIMUM_DOCKER_VERSION:
+ pytest.skip(
+ f"expected Docker version to be at least {'.'.join(self.MINIMUM_DOCKER_VERSION)}, found {'.'.join(version)}"
+ )
@property
@abstractmethod
@@ -186,6 +216,7 @@ def tag(self) -> str:
def check_skip(self):
"""Check if the test should be skipped."""
+ super().check_skip()
if sys.version_info < (3, 7):
pytest.skip("Python version < 3.7 not supported by the OEF.")
return
diff --git a/tests/common/utils.py b/tests/common/utils.py
index ba21020c0b..30b1720057 100644
--- a/tests/common/utils.py
+++ b/tests/common/utils.py
@@ -395,7 +395,6 @@ def run_aea_subprocess(*args, cwd: str = ".") -> Tuple[subprocess.Popen, str, st
return result, stdout.decode("utf-8"), stderr.decode("utf-8")
-@pytest.mark.skip_in_ci
@pytest.mark.integration
class UseOef: # pylint: disable=too-few-public-methods
"""Inherit from this class to launch an OEF node."""
diff --git a/tests/conftest.py b/tests/conftest.py
index 0a0387aa47..2f94ad344d 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1402,7 +1402,6 @@ def make_uri(addr: str, port: int):
return f"{addr}:{port}"
-@pytest.mark.skip_in_ci
@pytest.mark.integration
class UseGanache:
"""Inherit from this class to use Ganache."""
From 4eb90bde21ff05062631d70be91e1eff821d36e6 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 4 May 2021 19:18:43 +0200
Subject: [PATCH 003/147] remove calls to 'action_for_platform' with 'Linux'
superseded by changes in 4e9f343
---
tests/conftest.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/tests/conftest.py b/tests/conftest.py
index 2f94ad344d..da88ad5dfc 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -645,7 +645,6 @@ def apply_aea_loop(request) -> None:
@pytest.fixture(scope="session")
-@action_for_platform("Linux", skip=False)
def network_node(
oef_addr, oef_port, pytestconfig, timeout: float = 2.0, max_attempts: int = 10
):
@@ -706,7 +705,6 @@ def update_default_ethereum_ledger_api(ethereum_testnet_config):
@pytest.mark.integration
@pytest.mark.ledger
@pytest.fixture(scope="session")
-@action_for_platform("Linux", skip=False)
def ganache(
ganache_configuration,
ganache_addr,
From 2e98ec7a2b5bb2e3b5b0970b25990bc6207cd47e Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 5 May 2021 22:27:37 +0100
Subject: [PATCH 004/147] feat: update tac deployments
---
examples/tac_deploy/Dockerfile | 2 +-
examples/tac_deploy/README.md | 7 ++++---
examples/tac_deploy/data/.gitignore | 0
examples/tac_deploy/entrypoint.sh | 4 ++--
examples/tac_deploy/tac-deployment.yaml | 6 +++---
packages/fetchai/connections/p2p_libp2p/connection.py | 2 +-
packages/fetchai/connections/p2p_libp2p/connection.yaml | 2 +-
packages/hashes.csv | 2 +-
scripts/bump_aea_version.py | 1 +
9 files changed, 14 insertions(+), 12 deletions(-)
delete mode 100644 examples/tac_deploy/data/.gitignore
diff --git a/examples/tac_deploy/Dockerfile b/examples/tac_deploy/Dockerfile
index 6bb96e7290..65c40aa990 100644
--- a/examples/tac_deploy/Dockerfile
+++ b/examples/tac_deploy/Dockerfile
@@ -16,7 +16,7 @@ RUN apk add --no-cache go
# aea installation
RUN python -m pip install --upgrade pip
-RUN pip install --upgrade --force-reinstall aea[all]==1.0.0
+RUN pip install --upgrade --force-reinstall aea[all]==1.0.1
# directories and aea cli config
COPY /.aea /home/.aea
diff --git a/examples/tac_deploy/README.md b/examples/tac_deploy/README.md
index f26151add3..692e7c619e 100644
--- a/examples/tac_deploy/README.md
+++ b/examples/tac_deploy/README.md
@@ -29,19 +29,19 @@ GCloud should be configured first!
Tag the image first with the latest tag:
``` bash
-docker image tag tac-deploy gcr.io/fetch-ai-sandbox/tac_deploy:0.0.7
+docker image tag tac-deploy gcr.io/fetch-ai-sandbox/tac_deploy:0.0.10
```
Push it to remote repo:
``` bash
-docker push gcr.io/fetch-ai-sandbox/tac_deploy:0.0.7
+docker push gcr.io/fetch-ai-sandbox/tac_deploy:0.0.10
```
### Run it manually
Run it
``` bash
-kubectl run tac-deploy-{SOMETHING} --image=gcr.io/fetch-ai-sandbox/tac_deploy:0.0.7 --env="PARTICIPANTS_AMOUNT=5" --attach
+kubectl run tac-deploy-{SOMETHING} --image=gcr.io/fetch-ai-sandbox/tac_deploy:0.0.10 --env="PARTICIPANTS_AMOUNT=5" --attach
```
Or simply restart existing deployment and latest image will be used with default configurations (see below):
@@ -96,6 +96,7 @@ grep -rl 'TAKE CARE! Circumventing controller identity check!' output_dir/ | wc
grep -rnw 'SOEF Network Connection Error' output_dir/ | wc -l
grep -rnw 'SOEF Server Bad Response Error' output_dir/ | wc -l
grep -rnw 'Failure during pipe closing.' output_dir/ | wc -l
+grep -rnw "Couldn't connect to libp2p process within timeout" output_dir/ | wc -l
grep -rnw 'Exception' output_dir/ | wc -l
grep -rnw 'connect to libp2p process within timeout' output_dir/ | wc -l
grep -rnw 'handling valid transaction' output_dir/tac_controller/ | wc -l
diff --git a/examples/tac_deploy/data/.gitignore b/examples/tac_deploy/data/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/examples/tac_deploy/entrypoint.sh b/examples/tac_deploy/entrypoint.sh
index 4028903bff..40c10884c3 100755
--- a/examples/tac_deploy/entrypoint.sh
+++ b/examples/tac_deploy/entrypoint.sh
@@ -52,7 +52,7 @@ echo CLEANUP_INTERVAL $CLEANUP_INTERVAL
if [ -z "$NODE_CONNECTION_TIMEOUT" ];
then
- NODE_CONNECTION_TIMEOUT=20
+ NODE_CONNECTION_TIMEOUT=30
fi
echo NODE_CONNECTION_TIMEOUT $NODE_CONNECTION_TIMEOUT
@@ -115,7 +115,7 @@ function set_agent(){
key_file_name=$(generate_key $LEDGER $name $agent_data_dir 1)
aea add-key fetchai $key_file_name --connection
aea issue-certificates
- json=$(printf '{"log_file": "%s", "delegate_uri": null, "entry_peers": ["%s"], "local_uri": "127.0.0.1:%s", "public_uri": null}' "$agent_data_dir/libp2p_node.log" "$PEER" "$port")
+ json=$(printf '{"log_file": "%s", "delegate_uri": null, "entry_peers": ["%s"], "local_uri": "127.0.0.1:%s", "public_uri": null, "node_connection_timeout": '%i'}' "$agent_data_dir/libp2p_node.log" "$PEER" "$port" "$(($NODE_CONNECTION_TIMEOUT))")
aea config set --type dict vendor.fetchai.connections.p2p_libp2p.config "$json"
log_file=$agent_data_dir/$name.log
json=$(printf '{"version": 1, "formatters": {"standard": {"format": ""}}, "handlers": {"console": {"class": "logging.StreamHandler", "formatter": "standard", "level": "%s"}, "file": {"class": "logging.FileHandler", "filename": "%s", "mode": "w", "level": "%s", "formatter": "standard"}}, "loggers": {"aea": {"level": "%s", "handlers": ["file"]}}}' "$LOG_LEVEL" "$log_file" "$LOG_LEVEL" "$LOG_LEVEL")
diff --git a/examples/tac_deploy/tac-deployment.yaml b/examples/tac_deploy/tac-deployment.yaml
index 3a2bc579bf..cb8ffc8f46 100644
--- a/examples/tac_deploy/tac-deployment.yaml
+++ b/examples/tac_deploy/tac-deployment.yaml
@@ -18,7 +18,7 @@ spec:
kubernetes.io/os: linux
containers:
- name: tac-deploy-container
- image: gcr.io/fetch-ai-sandbox/tac_deploy:0.0.7
+ image: gcr.io/fetch-ai-sandbox/tac_deploy:0.0.10
env:
- name: PARTICIPANTS_AMOUNT
value: "70"
@@ -35,13 +35,13 @@ spec:
- name: CLEANUP_INTERVAL
value: "1800"
- name: NODE_CONNECTION_TIMEOUT
- value: "20"
+ value: "30"
- name: LOG_LEVEL
value: "INFO"
- name: CLEAR_LOG_DATA_ON_LAUNCH
value: "true"
- name: CLEAR_KEY_DATA_ON_LAUNCH
- value: "false"
+ value: "true"
volumeMounts:
- name: tac-deploy-data-vol
mountPath: /data
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.py b/packages/fetchai/connections/p2p_libp2p/connection.py
index b7a80d822e..7e39d56e2f 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.py
+++ b/packages/fetchai/connections/p2p_libp2p/connection.py
@@ -338,7 +338,7 @@ def get_client(self) -> NodeClient:
return NodeClient(self.pipe)
- def _child_watcher_callback(self, *_) -> None: # type:ignore
+ def _child_watcher_callback(self, *_) -> None: # pragma: nocover # type: ignore
"""Log if process was terminated before stop was called."""
if self._is_on_stop:
return
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index 8335d1a390..2198c8f425 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -11,7 +11,7 @@ fingerprint:
README.md: QmWcd2zHiRZLgXCSGw9gZ35WfcKsMeNSQouqNAaZnPBDDR
__init__.py: QmYQuLNyQ8WTjgRYAoKAzoJEb7ocKXvM2hTyK4hsGch5D6
check_dependencies.py: QmP14nkQ8senwzdPdrZJLsA6EQ7zaKKEaLGDELhT42gp1P
- connection.py: Qmcu4UDCoJZrd6jkDwHwZ9B863SpdAnWTjg5gssn7C1gjo
+ connection.py: QmadFUy2C1igQHWwfgi5p18CMqKh9RAq42imuiEc62bAV1
libp2p_node/README.md: QmSNJEQQwh25QSHgQPM4C84xKU6FczRpmJdN7HkCQyDPuC
libp2p_node/aea/api.go: QmdFR5Rmkk2FGVDwzgHtjobjAKyLejqk2CAYBCvcF23AG7
libp2p_node/aea/envelope.pb.go: QmRfUNGpCeVJfsW3H1MzCN4pwDWgumfyWufVFp6xvUjjug
diff --git a/packages/hashes.csv b/packages/hashes.csv
index fc6270513b..a60234e214 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmP8QtMAxuFHrPuwqg9pxnVzGcBs4fCL47pjkSDdK5fZna
+fetchai/connections/p2p_libp2p,QmaW6tC7aQww1XbDrhcPXTMtJkcEPUMRsVANUP9heY1eR7
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index fa2a905705..c5154138ca 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -71,6 +71,7 @@ def update_version_for_files(current_version: str, new_version: str) -> None:
Path("deploy-image", "Dockerfile"),
Path("develop-image", "docker-env.sh"),
Path("docs", "quickstart.md"),
+ Path("examples", "tac_deploy", "Dockerfile"),
Path("scripts", "install.ps1"),
Path("scripts", "install.sh"),
Path("tests", "test_docs", "test_bash_yaml", "md_files", "bash-quickstart.md"),
From b4406fb721f3e975f6dade561a760dd94b3f21f3 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Thu, 6 May 2021 09:39:59 +0100
Subject: [PATCH 005/147] fix: static lint issue
---
packages/fetchai/connections/p2p_libp2p/connection.py | 2 +-
packages/fetchai/connections/p2p_libp2p/connection.yaml | 2 +-
packages/hashes.csv | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.py b/packages/fetchai/connections/p2p_libp2p/connection.py
index 7e39d56e2f..825be23bb3 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.py
+++ b/packages/fetchai/connections/p2p_libp2p/connection.py
@@ -338,7 +338,7 @@ def get_client(self) -> NodeClient:
return NodeClient(self.pipe)
- def _child_watcher_callback(self, *_) -> None: # pragma: nocover # type: ignore
+ def _child_watcher_callback(self, *_) -> None: # type: ignore # pragma: nocover
"""Log if process was terminated before stop was called."""
if self._is_on_stop:
return
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index 2198c8f425..f9e7eb46d7 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -11,7 +11,7 @@ fingerprint:
README.md: QmWcd2zHiRZLgXCSGw9gZ35WfcKsMeNSQouqNAaZnPBDDR
__init__.py: QmYQuLNyQ8WTjgRYAoKAzoJEb7ocKXvM2hTyK4hsGch5D6
check_dependencies.py: QmP14nkQ8senwzdPdrZJLsA6EQ7zaKKEaLGDELhT42gp1P
- connection.py: QmadFUy2C1igQHWwfgi5p18CMqKh9RAq42imuiEc62bAV1
+ connection.py: QmecxEkWQijRvcaaok2pJdEatvLBTad6Vi9f721VLnvdks
libp2p_node/README.md: QmSNJEQQwh25QSHgQPM4C84xKU6FczRpmJdN7HkCQyDPuC
libp2p_node/aea/api.go: QmdFR5Rmkk2FGVDwzgHtjobjAKyLejqk2CAYBCvcF23AG7
libp2p_node/aea/envelope.pb.go: QmRfUNGpCeVJfsW3H1MzCN4pwDWgumfyWufVFp6xvUjjug
diff --git a/packages/hashes.csv b/packages/hashes.csv
index a60234e214..1f8ad50875 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmaW6tC7aQww1XbDrhcPXTMtJkcEPUMRsVANUP9heY1eR7
+fetchai/connections/p2p_libp2p,Qme5ykdVah3sDnDkEXUycctPay1LtbRPwMBsQR2sErVJVk
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
From ecc182907d038ded78d1b27f359d50f6ec4b338c Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Thu, 6 May 2021 10:54:22 +0100
Subject: [PATCH 006/147] feat: extend tac deploy to support p2p client
---
examples/tac_deploy/.env | 3 ++-
examples/tac_deploy/build.sh | 18 ++++++++++++++++++
examples/tac_deploy/entrypoint.sh | 7 +++++--
3 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/examples/tac_deploy/.env b/examples/tac_deploy/.env
index 30db21cc04..41ee901589 100644
--- a/examples/tac_deploy/.env
+++ b/examples/tac_deploy/.env
@@ -1,2 +1,3 @@
PARTICIPANTS_AMOUNT=2
-LOG_LEVEL=DEBUG
\ No newline at end of file
+LOG_LEVEL=DEBUG
+USE_CLIENT=true
\ No newline at end of file
diff --git a/examples/tac_deploy/build.sh b/examples/tac_deploy/build.sh
index b92558f735..300d4441f1 100644
--- a/examples/tac_deploy/build.sh
+++ b/examples/tac_deploy/build.sh
@@ -1,17 +1,35 @@
#!/bin/bash
set -e
+if [ -z "$USE_CLIENT" ];
+then
+ USE_CLIENT=false
+fi
+echo USE_CLIENT $USE_CLIENT
+
mkdir /data
# setup the agent
aea fetch fetchai/tac_controller:latest
cd tac_controller
+if [[ "$USE_CLIENT" ]]
+then
+ aea remove connection fetchai/p2p_libp2p
+ aea add connection fetchai/p2p_libp2p_client
+ aea config set agent.default_connection fetchai/p2p_libp2p_client:0.18.0
+fi
aea install
aea build
cd ..
aea fetch fetchai/tac_participant:latest --alias tac_participant_template
cd tac_participant_template
+if [[ "$USE_CLIENT" ]]
+then
+ aea remove connection fetchai/p2p_libp2p
+ aea add connection fetchai/p2p_libp2p_client
+ aea config set agent.default_connection fetchai/p2p_libp2p_client:0.18.0
+fi
aea install
aea build
cd ..
diff --git a/examples/tac_deploy/entrypoint.sh b/examples/tac_deploy/entrypoint.sh
index 40c10884c3..bbd0024fdc 100755
--- a/examples/tac_deploy/entrypoint.sh
+++ b/examples/tac_deploy/entrypoint.sh
@@ -114,9 +114,12 @@ function set_agent(){
aea add-key fetchai $key_file_name
key_file_name=$(generate_key $LEDGER $name $agent_data_dir 1)
aea add-key fetchai $key_file_name --connection
+ if [[ ! "$USE_CLIENT" ]]
+ then
+ json=$(printf '{"log_file": "%s", "delegate_uri": null, "entry_peers": ["%s"], "local_uri": "127.0.0.1:%s", "public_uri": null, "node_connection_timeout": '%i'}' "$agent_data_dir/libp2p_node.log" "$PEER" "$port" "$(($NODE_CONNECTION_TIMEOUT))")
+ aea config set --type dict vendor.fetchai.connections.p2p_libp2p.config "$json"
+ fi
aea issue-certificates
- json=$(printf '{"log_file": "%s", "delegate_uri": null, "entry_peers": ["%s"], "local_uri": "127.0.0.1:%s", "public_uri": null, "node_connection_timeout": '%i'}' "$agent_data_dir/libp2p_node.log" "$PEER" "$port" "$(($NODE_CONNECTION_TIMEOUT))")
- aea config set --type dict vendor.fetchai.connections.p2p_libp2p.config "$json"
log_file=$agent_data_dir/$name.log
json=$(printf '{"version": 1, "formatters": {"standard": {"format": ""}}, "handlers": {"console": {"class": "logging.StreamHandler", "formatter": "standard", "level": "%s"}, "file": {"class": "logging.FileHandler", "filename": "%s", "mode": "w", "level": "%s", "formatter": "standard"}}, "loggers": {"aea": {"level": "%s", "handlers": ["file"]}}}' "$LOG_LEVEL" "$log_file" "$LOG_LEVEL" "$LOG_LEVEL")
aea config set --type dict agent.logging_config "$json"
From 4eaf4f32f33f63b0c9bc568f3150cc18941ebe96 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Thu, 6 May 2021 15:08:34 +0300
Subject: [PATCH 007/147] libp2p connection tcpsocket usage for every platform
---
examples/tac_deploy/Dockerfile | 3 +
examples/tac_deploy/build.sh | 10 +--
.../aea/{pipe_windows.go => pipe.go} | 2 +-
libs/go/libp2p_node/aea/pipe_unix.go | 90 -------------------
.../connections/p2p_libp2p/connection.py | 6 +-
.../connections/p2p_libp2p/connection.yaml | 5 +-
.../aea/{pipe_windows.go => pipe.go} | 2 +-
.../p2p_libp2p/libp2p_node/aea/pipe_unix.go | 90 -------------------
packages/hashes.csv | 2 +-
9 files changed, 16 insertions(+), 194 deletions(-)
rename libs/go/libp2p_node/aea/{pipe_windows.go => pipe.go} (98%)
delete mode 100644 libs/go/libp2p_node/aea/pipe_unix.go
rename packages/fetchai/connections/p2p_libp2p/libp2p_node/aea/{pipe_windows.go => pipe.go} (98%)
delete mode 100644 packages/fetchai/connections/p2p_libp2p/libp2p_node/aea/pipe_unix.go
diff --git a/examples/tac_deploy/Dockerfile b/examples/tac_deploy/Dockerfile
index 65c40aa990..74c0c73e1b 100644
--- a/examples/tac_deploy/Dockerfile
+++ b/examples/tac_deploy/Dockerfile
@@ -2,6 +2,9 @@ FROM python:3.8-alpine
USER root
+ARG USE_CLIENT
+ENV USE_CLIENT=$USE_CLIENT
+
RUN apk add --no-cache make git bash
# cryptography: https://cryptography.io/en/latest/installation/#alpine
diff --git a/examples/tac_deploy/build.sh b/examples/tac_deploy/build.sh
index 300d4441f1..447274f352 100644
--- a/examples/tac_deploy/build.sh
+++ b/examples/tac_deploy/build.sh
@@ -1,7 +1,7 @@
#!/bin/bash
set -e
-if [ -z "$USE_CLIENT" ];
+if [ -z "$USE_CLIENT" ];
then
USE_CLIENT=false
fi
@@ -10,9 +10,9 @@ echo USE_CLIENT $USE_CLIENT
mkdir /data
# setup the agent
-aea fetch fetchai/tac_controller:latest
+aea fetch --local fetchai/tac_controller:latest
cd tac_controller
-if [[ "$USE_CLIENT" ]]
+if [[ "$USE_CLIENT" == "true" ]]
then
aea remove connection fetchai/p2p_libp2p
aea add connection fetchai/p2p_libp2p_client
@@ -22,9 +22,9 @@ aea install
aea build
cd ..
-aea fetch fetchai/tac_participant:latest --alias tac_participant_template
+aea fetch --local fetchai/tac_participant:latest --alias tac_participant_template
cd tac_participant_template
-if [[ "$USE_CLIENT" ]]
+if [[ "$USE_CLIENT" == "true" ]]
then
aea remove connection fetchai/p2p_libp2p
aea add connection fetchai/p2p_libp2p_client
diff --git a/libs/go/libp2p_node/aea/pipe_windows.go b/libs/go/libp2p_node/aea/pipe.go
similarity index 98%
rename from libs/go/libp2p_node/aea/pipe_windows.go
rename to libs/go/libp2p_node/aea/pipe.go
index 54efa060c7..b020d2b444 100644
--- a/libs/go/libp2p_node/aea/pipe_windows.go
+++ b/libs/go/libp2p_node/aea/pipe.go
@@ -1,4 +1,4 @@
-// +build windows !linux !darwin
+// +build windows linux darwin
/* -*- coding: utf-8 -*-
* ------------------------------------------------------------------------------
diff --git a/libs/go/libp2p_node/aea/pipe_unix.go b/libs/go/libp2p_node/aea/pipe_unix.go
deleted file mode 100644
index 9b03e165da..0000000000
--- a/libs/go/libp2p_node/aea/pipe_unix.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// +build linux darwin !windows
-
-/* -*- coding: utf-8 -*-
-* ------------------------------------------------------------------------------
-*
-* Copyright 2018-2019 Fetch.AI Limited
-*
-* 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.
-*
-* ------------------------------------------------------------------------------
- */
-
-package aea
-
-import (
- "encoding/binary"
- "errors"
- "math"
- "os"
-)
-
-type UnixPipe struct {
- msgin_path string
- msgout_path string
- msgin *os.File
- msgout *os.File
-}
-
-func (pipe *UnixPipe) Connect() error {
- // open pipes
- var erro, erri error
- pipe.msgout, erro = os.OpenFile(pipe.msgout_path, os.O_WRONLY, os.ModeNamedPipe)
- pipe.msgin, erri = os.OpenFile(pipe.msgin_path, os.O_RDONLY, os.ModeNamedPipe)
-
- if erri != nil || erro != nil {
- if erri != nil {
- return erri
- }
- return erro
- }
-
- return nil
-}
-
-func (pipe *UnixPipe) Read() ([]byte, error) {
- buf := make([]byte, 4)
- _, err := pipe.msgin.Read(buf)
- if err != nil {
- return buf, errors.New("while receiving size" + err.Error())
- }
- size := binary.BigEndian.Uint32(buf)
-
- buf = make([]byte, size)
- _, err = pipe.msgin.Read(buf)
- return buf, err
-
-}
-
-func (pipe *UnixPipe) Write(data []byte) error {
- if len(data) > math.MaxInt32 {
- return errors.New("value too large")
- }
- size := uint32(len(data))
- buf := make([]byte, 4, 4+size)
- binary.BigEndian.PutUint32(buf, size)
- buf = append(buf, data...)
- _, err := pipe.msgout.Write(buf)
- logger.Debug().Msgf("wrote data to pipe: %d bytes", size)
- return err
-}
-
-func (pipe *UnixPipe) Close() error {
- pipe.msgin.Close()
- pipe.msgout.Close()
- return nil
-}
-
-func NewPipe(msgin_path string, msgout_path string) Pipe {
- return &UnixPipe{msgin_path: msgin_path, msgout_path: msgout_path, msgin: nil, msgout: nil}
-}
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.py b/packages/fetchai/connections/p2p_libp2p/connection.py
index 825be23bb3..32ec7eb3b1 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.py
+++ b/packages/fetchai/connections/p2p_libp2p/connection.py
@@ -37,7 +37,7 @@
from aea.helpers.acn.agent_record import AgentRecord
from aea.helpers.acn.uri import Uri
from aea.helpers.multiaddr.base import MultiAddr
-from aea.helpers.pipe import IPCChannel, make_ipc_channel
+from aea.helpers.pipe import IPCChannel, TCPSocketChannel
from aea.mail.base import Envelope
@@ -364,8 +364,8 @@ async def start(self) -> None:
self._log_file_desc.write("test")
self._log_file_desc.flush()
- # setup fifos or tcp socket on windows
- self.pipe = make_ipc_channel(logger=self.logger)
+ # tcp socket on every platform
+ self.pipe = TCPSocketChannel(logger=self.logger)
env_file_data = self._make_env_file(
pipe_in_path=self.pipe.in_path, pipe_out_path=self.pipe.out_path
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index f9e7eb46d7..787e0c7fdb 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -11,13 +11,12 @@ fingerprint:
README.md: QmWcd2zHiRZLgXCSGw9gZ35WfcKsMeNSQouqNAaZnPBDDR
__init__.py: QmYQuLNyQ8WTjgRYAoKAzoJEb7ocKXvM2hTyK4hsGch5D6
check_dependencies.py: QmP14nkQ8senwzdPdrZJLsA6EQ7zaKKEaLGDELhT42gp1P
- connection.py: QmecxEkWQijRvcaaok2pJdEatvLBTad6Vi9f721VLnvdks
+ connection.py: Qma7YF3frWSKL92FaScmGtR1QmQgvM9QPBdWZPPgHRcTzh
libp2p_node/README.md: QmSNJEQQwh25QSHgQPM4C84xKU6FczRpmJdN7HkCQyDPuC
libp2p_node/aea/api.go: QmdFR5Rmkk2FGVDwzgHtjobjAKyLejqk2CAYBCvcF23AG7
libp2p_node/aea/envelope.pb.go: QmRfUNGpCeVJfsW3H1MzCN4pwDWgumfyWufVFp6xvUjjug
libp2p_node/aea/envelope.proto: QmVuvesmfgzj5aKnbFoCocoGEv3T9MR7u6KWn7CT5yfjGi
- libp2p_node/aea/pipe_unix.go: QmYC7pExTkBBNHnbBeyd4HKmj9fDTnouS4apbwZoGXNWJz
- libp2p_node/aea/pipe_windows.go: QmNcuPLMsbdWqUn1SFx2V2RTkujjtvBfYQmavz6QiZx6av
+ libp2p_node/aea/pipe.go: QmWLBjZNRCcg3BSM9Cxb95yAXdT6wPjgw8DSYHxMuux4JA
libp2p_node/dht/dhtclient/dhtclient.go: QmYFj4YghhVA7E976xLNQHRTGrik1uHLc6ZQ9Tw1p9ECzk
libp2p_node/dht/dhtclient/dhtclient_test.go: QmS9SiLAojXYobqV9m5yeRpyPzt6JcSbQD78RNvSp6LPx6
libp2p_node/dht/dhtclient/options.go: QmaoJiavHescgx98inQjVUipPFRvcFFrodrScZ3fvrXJ4z
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/aea/pipe_windows.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/aea/pipe.go
similarity index 98%
rename from packages/fetchai/connections/p2p_libp2p/libp2p_node/aea/pipe_windows.go
rename to packages/fetchai/connections/p2p_libp2p/libp2p_node/aea/pipe.go
index 54efa060c7..b020d2b444 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/aea/pipe_windows.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/aea/pipe.go
@@ -1,4 +1,4 @@
-// +build windows !linux !darwin
+// +build windows linux darwin
/* -*- coding: utf-8 -*-
* ------------------------------------------------------------------------------
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/aea/pipe_unix.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/aea/pipe_unix.go
deleted file mode 100644
index 9b03e165da..0000000000
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/aea/pipe_unix.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// +build linux darwin !windows
-
-/* -*- coding: utf-8 -*-
-* ------------------------------------------------------------------------------
-*
-* Copyright 2018-2019 Fetch.AI Limited
-*
-* 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.
-*
-* ------------------------------------------------------------------------------
- */
-
-package aea
-
-import (
- "encoding/binary"
- "errors"
- "math"
- "os"
-)
-
-type UnixPipe struct {
- msgin_path string
- msgout_path string
- msgin *os.File
- msgout *os.File
-}
-
-func (pipe *UnixPipe) Connect() error {
- // open pipes
- var erro, erri error
- pipe.msgout, erro = os.OpenFile(pipe.msgout_path, os.O_WRONLY, os.ModeNamedPipe)
- pipe.msgin, erri = os.OpenFile(pipe.msgin_path, os.O_RDONLY, os.ModeNamedPipe)
-
- if erri != nil || erro != nil {
- if erri != nil {
- return erri
- }
- return erro
- }
-
- return nil
-}
-
-func (pipe *UnixPipe) Read() ([]byte, error) {
- buf := make([]byte, 4)
- _, err := pipe.msgin.Read(buf)
- if err != nil {
- return buf, errors.New("while receiving size" + err.Error())
- }
- size := binary.BigEndian.Uint32(buf)
-
- buf = make([]byte, size)
- _, err = pipe.msgin.Read(buf)
- return buf, err
-
-}
-
-func (pipe *UnixPipe) Write(data []byte) error {
- if len(data) > math.MaxInt32 {
- return errors.New("value too large")
- }
- size := uint32(len(data))
- buf := make([]byte, 4, 4+size)
- binary.BigEndian.PutUint32(buf, size)
- buf = append(buf, data...)
- _, err := pipe.msgout.Write(buf)
- logger.Debug().Msgf("wrote data to pipe: %d bytes", size)
- return err
-}
-
-func (pipe *UnixPipe) Close() error {
- pipe.msgin.Close()
- pipe.msgout.Close()
- return nil
-}
-
-func NewPipe(msgin_path string, msgout_path string) Pipe {
- return &UnixPipe{msgin_path: msgin_path, msgout_path: msgout_path, msgin: nil, msgout: nil}
-}
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 1f8ad50875..9e87b675e6 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,Qme5ykdVah3sDnDkEXUycctPay1LtbRPwMBsQR2sErVJVk
+fetchai/connections/p2p_libp2p,QmSLPfHt1ow8EDGBtbRvDh7TetXeXpS5ju2eThd5WR3bF4
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
From 1bc62c0b80dd611c46bc0b71d18edda4b25bf2c7 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Thu, 6 May 2021 15:53:26 +0300
Subject: [PATCH 008/147] fix for build.sh of tac deployment example
---
examples/tac_deploy/build.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/examples/tac_deploy/build.sh b/examples/tac_deploy/build.sh
index 447274f352..21e74af0eb 100644
--- a/examples/tac_deploy/build.sh
+++ b/examples/tac_deploy/build.sh
@@ -10,7 +10,7 @@ echo USE_CLIENT $USE_CLIENT
mkdir /data
# setup the agent
-aea fetch --local fetchai/tac_controller:latest
+aea fetch fetchai/tac_controller:latest
cd tac_controller
if [[ "$USE_CLIENT" == "true" ]]
then
@@ -22,7 +22,7 @@ aea install
aea build
cd ..
-aea fetch --local fetchai/tac_participant:latest --alias tac_participant_template
+aea fetch fetchai/tac_participant:latest --alias tac_participant_template
cd tac_participant_template
if [[ "$USE_CLIENT" == "true" ]]
then
From d25e39b9c4155b838fdf5caaca6501b11eb8de83 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Thu, 6 May 2021 18:02:00 +0100
Subject: [PATCH 009/147] fix: add nil check for stream in p2p node
---
libs/go/libp2p_node/utils/utils.go | 78 +++----------------
.../connections/p2p_libp2p/connection.yaml | 2 +-
.../p2p_libp2p/libp2p_node/utils/utils.go | 78 +++----------------
packages/hashes.csv | 2 +-
4 files changed, 20 insertions(+), 140 deletions(-)
diff --git a/libs/go/libp2p_node/utils/utils.go b/libs/go/libp2p_node/utils/utils.go
index c5cb0d3719..92a01b0648 100644
--- a/libs/go/libp2p_node/utils/utils.go
+++ b/libs/go/libp2p_node/utils/utils.go
@@ -669,6 +669,9 @@ func ReadEnvelopeConn(conn net.Conn) (*aea.Envelope, error) {
// ReadBytes from a network stream
func ReadBytes(s network.Stream) ([]byte, error) {
+ if s == nil {
+ panic("GOTCHAAAAAAA 1, can not write to nil stream")
+ }
rstream := bufio.NewReader(s)
buf := make([]byte, 4)
@@ -703,6 +706,9 @@ func WriteBytes(s network.Stream, data []byte) error {
return nil
}
+ if s == nil {
+ panic("GOTCHAAAAAAA 1, can not write to nil stream")
+ }
wstream := bufio.NewWriter(s)
size := uint32(len(data))
@@ -724,6 +730,9 @@ func WriteBytes(s network.Stream, data []byte) error {
Msg("Error on data write")
return err
}
+ if s == nil {
+ panic("GOTCHAAAAAAA 2, can not write to nil stream")
+ }
err = wstream.Flush()
if err != nil {
logger.Error().
@@ -733,72 +742,3 @@ func WriteBytes(s network.Stream, data []byte) error {
}
return err
}
-
-// ReadString from a network stream
-func ReadString(s network.Stream) (string, error) {
- data, err := ReadBytes(s)
- return string(data), err
-}
-
-// WriteEnvelope to a network stream
-func WriteEnvelope(envel *aea.Envelope, s network.Stream) error {
- wstream := bufio.NewWriter(s)
- data, err := proto.Marshal(envel)
- if err != nil {
- return err
- }
- size := uint32(len(data))
-
- buf := make([]byte, 4)
- binary.BigEndian.PutUint32(buf, size)
- //log.Println("DEBUG writing size:", size, buf)
- _, err = wstream.Write(buf)
- if err != nil {
- return err
- }
-
- //log.Println("DEBUG writing data:", data)
- _, err = wstream.Write(data)
- if err != nil {
- return err
- }
-
- err = wstream.Flush()
- if err != nil {
- return err
- }
- return nil
-}
-
-// ReadEnvelope from a network stream
-func ReadEnvelope(s network.Stream) (*aea.Envelope, error) {
- envel := &aea.Envelope{}
- rstream := bufio.NewReader(s)
-
- buf := make([]byte, 4)
- _, err := io.ReadFull(rstream, buf)
-
- if err != nil {
- logger.Error().
- Str("err", err.Error()).
- Msg("while reading size")
- return envel, err
- }
-
- size := binary.BigEndian.Uint32(buf)
- if size > maxMessageSizeDelegateConnection {
- return nil, errors.New("Expected message size larger than maximum allowed")
- }
- //logger.Debug().Msgf("received size: %d %x", size, buf)
- buf = make([]byte, size)
- _, err = io.ReadFull(rstream, buf)
- if err != nil {
- logger.Error().
- Str("err", err.Error()).
- Msg("while reading data")
- return envel, err
- }
-
- err = proto.Unmarshal(buf, envel)
- return envel, err
-}
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index 787e0c7fdb..13bf2ff4b9 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -36,7 +36,7 @@ fingerprint:
libp2p_node/go.mod: QmT2LQXkSen6Th4QLS2RU3tRVxJSLjdZTxRULUcnQFXfEL
libp2p_node/go.sum: QmZc6oiDqQhB6ZKVojN26JxoTNH1QetyuYd9zjSksQnTFt
libp2p_node/libp2p_node.go: QmSu21WBmAAfBbZFi3MZZgTrUMK5FYruSunxghpeUhxBMA
- libp2p_node/utils/utils.go: QmZQAY5CMRsqK36Zgy4ukgGzu7W5EVCQJGFhf6gJ9XCYNg
+ libp2p_node/utils/utils.go: QmYKmPHnv9RHzw1XbyBvTN57jPojxGiTM3v23rdKxKFW2R
fingerprint_ignore_patterns: []
build_entrypoint: check_dependencies.py
connections: []
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
index c5cb0d3719..92a01b0648 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
@@ -669,6 +669,9 @@ func ReadEnvelopeConn(conn net.Conn) (*aea.Envelope, error) {
// ReadBytes from a network stream
func ReadBytes(s network.Stream) ([]byte, error) {
+ if s == nil {
+ panic("GOTCHAAAAAAA 1, can not write to nil stream")
+ }
rstream := bufio.NewReader(s)
buf := make([]byte, 4)
@@ -703,6 +706,9 @@ func WriteBytes(s network.Stream, data []byte) error {
return nil
}
+ if s == nil {
+ panic("GOTCHAAAAAAA 1, can not write to nil stream")
+ }
wstream := bufio.NewWriter(s)
size := uint32(len(data))
@@ -724,6 +730,9 @@ func WriteBytes(s network.Stream, data []byte) error {
Msg("Error on data write")
return err
}
+ if s == nil {
+ panic("GOTCHAAAAAAA 2, can not write to nil stream")
+ }
err = wstream.Flush()
if err != nil {
logger.Error().
@@ -733,72 +742,3 @@ func WriteBytes(s network.Stream, data []byte) error {
}
return err
}
-
-// ReadString from a network stream
-func ReadString(s network.Stream) (string, error) {
- data, err := ReadBytes(s)
- return string(data), err
-}
-
-// WriteEnvelope to a network stream
-func WriteEnvelope(envel *aea.Envelope, s network.Stream) error {
- wstream := bufio.NewWriter(s)
- data, err := proto.Marshal(envel)
- if err != nil {
- return err
- }
- size := uint32(len(data))
-
- buf := make([]byte, 4)
- binary.BigEndian.PutUint32(buf, size)
- //log.Println("DEBUG writing size:", size, buf)
- _, err = wstream.Write(buf)
- if err != nil {
- return err
- }
-
- //log.Println("DEBUG writing data:", data)
- _, err = wstream.Write(data)
- if err != nil {
- return err
- }
-
- err = wstream.Flush()
- if err != nil {
- return err
- }
- return nil
-}
-
-// ReadEnvelope from a network stream
-func ReadEnvelope(s network.Stream) (*aea.Envelope, error) {
- envel := &aea.Envelope{}
- rstream := bufio.NewReader(s)
-
- buf := make([]byte, 4)
- _, err := io.ReadFull(rstream, buf)
-
- if err != nil {
- logger.Error().
- Str("err", err.Error()).
- Msg("while reading size")
- return envel, err
- }
-
- size := binary.BigEndian.Uint32(buf)
- if size > maxMessageSizeDelegateConnection {
- return nil, errors.New("Expected message size larger than maximum allowed")
- }
- //logger.Debug().Msgf("received size: %d %x", size, buf)
- buf = make([]byte, size)
- _, err = io.ReadFull(rstream, buf)
- if err != nil {
- logger.Error().
- Str("err", err.Error()).
- Msg("while reading data")
- return envel, err
- }
-
- err = proto.Unmarshal(buf, envel)
- return envel, err
-}
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 9e87b675e6..9ca813ca11 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmSLPfHt1ow8EDGBtbRvDh7TetXeXpS5ju2eThd5WR3bF4
+fetchai/connections/p2p_libp2p,QmZ2BpAKYyuRno8diqN8sbWEzHkjnWgLGg2kWbcEDdWkEi
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
From 66ba2729a4d24398f82c37f3f340bade73afdb96 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Thu, 6 May 2021 20:49:31 +0100
Subject: [PATCH 010/147] fix: deployment tac configs
---
examples/tac_deploy/.env | 2 +-
examples/tac_deploy/README.md | 6 +++---
examples/tac_deploy/entrypoint.sh | 5 ++++-
examples/tac_deploy/tac-deployment.yaml | 2 +-
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/examples/tac_deploy/.env b/examples/tac_deploy/.env
index 41ee901589..ee6efd8383 100644
--- a/examples/tac_deploy/.env
+++ b/examples/tac_deploy/.env
@@ -1,3 +1,3 @@
PARTICIPANTS_AMOUNT=2
LOG_LEVEL=DEBUG
-USE_CLIENT=true
\ No newline at end of file
+USE_CLIENT=false
\ No newline at end of file
diff --git a/examples/tac_deploy/README.md b/examples/tac_deploy/README.md
index 692e7c619e..e0e6083689 100644
--- a/examples/tac_deploy/README.md
+++ b/examples/tac_deploy/README.md
@@ -29,19 +29,19 @@ GCloud should be configured first!
Tag the image first with the latest tag:
``` bash
-docker image tag tac-deploy gcr.io/fetch-ai-sandbox/tac_deploy:0.0.10
+docker image tag tac-deploy gcr.io/fetch-ai-sandbox/tac_deploy:0.0.13
```
Push it to remote repo:
``` bash
-docker push gcr.io/fetch-ai-sandbox/tac_deploy:0.0.10
+docker push gcr.io/fetch-ai-sandbox/tac_deploy:0.0.13
```
### Run it manually
Run it
``` bash
-kubectl run tac-deploy-{SOMETHING} --image=gcr.io/fetch-ai-sandbox/tac_deploy:0.0.10 --env="PARTICIPANTS_AMOUNT=5" --attach
+kubectl run tac-deploy-{SOMETHING} --image=gcr.io/fetch-ai-sandbox/tac_deploy:0.0.13 --env="PARTICIPANTS_AMOUNT=5" --attach
```
Or simply restart existing deployment and latest image will be used with default configurations (see below):
diff --git a/examples/tac_deploy/entrypoint.sh b/examples/tac_deploy/entrypoint.sh
index bbd0024fdc..c30f46dea9 100755
--- a/examples/tac_deploy/entrypoint.sh
+++ b/examples/tac_deploy/entrypoint.sh
@@ -6,6 +6,9 @@ PEER="/dns4/acn.fetch.ai/tcp/9001/p2p/16Uiu2HAmVWnopQAqq4pniYLw44VRvYxBUoRHqjz1H
TAC_NAME='some_tac_id'
BASE_PORT=10000
BASE_DIR=/data
+OLD_DIR=/$(date "+%d_%m_%Y_%H%M")
+
+cp -R "$BASE_DIR" "$OLD_DIR"
if [ -z "$COMPETITION_TIMEOUT" ];
then
@@ -114,7 +117,7 @@ function set_agent(){
aea add-key fetchai $key_file_name
key_file_name=$(generate_key $LEDGER $name $agent_data_dir 1)
aea add-key fetchai $key_file_name --connection
- if [[ ! "$USE_CLIENT" ]]
+ if [ "$USE_CLIENT" == false ];
then
json=$(printf '{"log_file": "%s", "delegate_uri": null, "entry_peers": ["%s"], "local_uri": "127.0.0.1:%s", "public_uri": null, "node_connection_timeout": '%i'}' "$agent_data_dir/libp2p_node.log" "$PEER" "$port" "$(($NODE_CONNECTION_TIMEOUT))")
aea config set --type dict vendor.fetchai.connections.p2p_libp2p.config "$json"
diff --git a/examples/tac_deploy/tac-deployment.yaml b/examples/tac_deploy/tac-deployment.yaml
index cb8ffc8f46..8b82f70e63 100644
--- a/examples/tac_deploy/tac-deployment.yaml
+++ b/examples/tac_deploy/tac-deployment.yaml
@@ -18,7 +18,7 @@ spec:
kubernetes.io/os: linux
containers:
- name: tac-deploy-container
- image: gcr.io/fetch-ai-sandbox/tac_deploy:0.0.10
+ image: gcr.io/fetch-ai-sandbox/tac_deploy:0.0.13
env:
- name: PARTICIPANTS_AMOUNT
value: "70"
From 9cd58ddcb0351988a82b598d21c64e23bf28975c Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Fri, 7 May 2021 10:57:07 +0100
Subject: [PATCH 011/147] fix: add nil check for stream
fix: linter errors from staticcheck
---
examples/tac_deploy/.env | 7 ++++---
libs/go/libp2p_node/README.md | 1 +
.../go/libp2p_node/dht/dhtclient/dhtclient.go | 5 +++--
libs/go/libp2p_node/dht/dhtnode/utils.go | 6 +++---
libs/go/libp2p_node/dht/dhtpeer/dhtpeer.go | 1 -
.../libp2p_node/dht/dhtpeer/dhtpeer_test.go | 1 -
libs/go/libp2p_node/dht/monitoring/file.go | 1 -
libs/go/libp2p_node/go.mod | 3 +--
libs/go/libp2p_node/go.sum | 6 ++++++
libs/go/libp2p_node/libp2p_node.go | 1 +
libs/go/libp2p_node/utils/utils.go | 16 +++++++--------
.../connections/p2p_libp2p/connection.yaml | 20 +++++++++----------
.../p2p_libp2p/libp2p_node/README.md | 1 +
.../libp2p_node/dht/dhtclient/dhtclient.go | 5 +++--
.../libp2p_node/dht/dhtnode/utils.go | 6 +++---
.../libp2p_node/dht/dhtpeer/dhtpeer.go | 1 -
.../libp2p_node/dht/dhtpeer/dhtpeer_test.go | 1 -
.../libp2p_node/dht/monitoring/file.go | 1 -
.../connections/p2p_libp2p/libp2p_node/go.mod | 3 +--
.../connections/p2p_libp2p/libp2p_node/go.sum | 6 ++++++
.../p2p_libp2p/libp2p_node/libp2p_node.go | 1 +
.../p2p_libp2p/libp2p_node/utils/utils.go | 16 +++++++--------
packages/hashes.csv | 2 +-
23 files changed, 61 insertions(+), 50 deletions(-)
diff --git a/examples/tac_deploy/.env b/examples/tac_deploy/.env
index ee6efd8383..0fd448f2f1 100644
--- a/examples/tac_deploy/.env
+++ b/examples/tac_deploy/.env
@@ -1,3 +1,4 @@
-PARTICIPANTS_AMOUNT=2
-LOG_LEVEL=DEBUG
-USE_CLIENT=false
\ No newline at end of file
+PARTICIPANTS_AMOUNT=10
+LOG_LEVEL=INFO
+USE_CLIENT=false
+CLEAR_KEY_DATA_ON_LAUNCH=true
\ No newline at end of file
diff --git a/libs/go/libp2p_node/README.md b/libs/go/libp2p_node/README.md
index d95ba19985..0d084a56dd 100644
--- a/libs/go/libp2p_node/README.md
+++ b/libs/go/libp2p_node/README.md
@@ -20,6 +20,7 @@ To lint:
``` bash
golines . -w
golangci-lint run
+staticcheck ./...
```
## Messaging patterns
diff --git a/libs/go/libp2p_node/dht/dhtclient/dhtclient.go b/libs/go/libp2p_node/dht/dhtclient/dhtclient.go
index e627a21684..e9f6278e27 100644
--- a/libs/go/libp2p_node/dht/dhtclient/dhtclient.go
+++ b/libs/go/libp2p_node/dht/dhtclient/dhtclient.go
@@ -306,7 +306,6 @@ func (dhtClient *DHTClient) bootstrapLoopUntilTimeout() error {
)
case <-ctx.Done():
sleepTime = 0
- break
}
if sleepTime == 0 {
break
@@ -338,12 +337,14 @@ func (dhtClient *DHTClient) newStreamLoopUntilTimeout(
stream, err = dhtClient.routedHost.NewStream(ctx, peerID, streamType)
case <-ctx.Done():
sleepTime = 0
- break
}
if sleepTime == 0 {
break
}
}
+ if stream == nil {
+ return stream, errors.New("stream nil" + err.Error())
+ }
// register again in case of disconnection
if disconnected {
err = dhtClient.registerAgentAddress()
diff --git a/libs/go/libp2p_node/dht/dhtnode/utils.go b/libs/go/libp2p_node/dht/dhtnode/utils.go
index bdd237a75b..acf9781075 100644
--- a/libs/go/libp2p_node/dht/dhtnode/utils.go
+++ b/libs/go/libp2p_node/dht/dhtnode/utils.go
@@ -67,7 +67,7 @@ func IsValidProofOfRepresentation(
// check public key matches
if record.PeerPublicKey != representativePeerPubKey {
- err := errors.New("Wrong peer public key, expected " + representativePeerPubKey)
+ err := errors.New("wrong peer public key, expected " + representativePeerPubKey)
response := &Status{Code: Status_ERROR_WRONG_PUBLIC_KEY, Msgs: []string{err.Error()}}
return response, err
}
@@ -76,7 +76,7 @@ func IsValidProofOfRepresentation(
addrFromPubKey, err := utils.AgentAddressFromPublicKey(record.LedgerId, record.PublicKey)
if err != nil || addrFromPubKey != record.Address {
if err == nil {
- err = errors.New("Agent address and public key don't match")
+ err = errors.New("agent address and public key don't match")
}
response := &Status{Code: Status_ERROR_WRONG_AGENT_ADDRESS}
return response, err
@@ -91,7 +91,7 @@ func IsValidProofOfRepresentation(
)
if !ok || err != nil {
if err == nil {
- err = errors.New("Signature is not valid")
+ err = errors.New("signature is not valid")
}
response := &Status{Code: Status_ERROR_INVALID_PROOF}
return response, err
diff --git a/libs/go/libp2p_node/dht/dhtpeer/dhtpeer.go b/libs/go/libp2p_node/dht/dhtpeer/dhtpeer.go
index f562cd3859..13b8bb4ca5 100644
--- a/libs/go/libp2p_node/dht/dhtpeer/dhtpeer.go
+++ b/libs/go/libp2p_node/dht/dhtpeer/dhtpeer.go
@@ -629,7 +629,6 @@ func (dhtPeer *DHTPeer) handleDelegateService(ready *sync.WaitGroup) {
go dhtPeer.handleNewDelegationConnection(conn)
}
case <-dhtPeer.closing:
- break
}
}
}
diff --git a/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go b/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go
index d7686e3e4d..07705ca253 100644
--- a/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go
+++ b/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go
@@ -1959,7 +1959,6 @@ func ensureAddressAnnounced(peers ...*DHTPeer) {
for !peer.addressAnnounced {
select {
case <-ctx.Done():
- break
case <-time.After(5 * time.Millisecond):
}
}
diff --git a/libs/go/libp2p_node/dht/monitoring/file.go b/libs/go/libp2p_node/dht/monitoring/file.go
index 7c8248db77..ca2b39d591 100644
--- a/libs/go/libp2p_node/dht/monitoring/file.go
+++ b/libs/go/libp2p_node/dht/monitoring/file.go
@@ -176,7 +176,6 @@ func (fm *FileMonitoring) Start() {
select {
case <-fm.closing:
file.Close()
- break
default:
ignore(file.Truncate(0))
_, err := file.Seek(0, 0)
diff --git a/libs/go/libp2p_node/go.mod b/libs/go/libp2p_node/go.mod
index e06f56bec4..a5d16c054d 100644
--- a/libs/go/libp2p_node/go.mod
+++ b/libs/go/libp2p_node/go.mod
@@ -27,8 +27,7 @@ require (
github.com/sirupsen/logrus v1.7.0 // indirect
golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9
golang.org/x/mod v0.4.0 // indirect
- golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
- golang.org/x/tools v0.0.0-20201215171152-6307297f4651 // indirect
google.golang.org/protobuf v1.25.0
+ honnef.co/go/tools v0.1.4 // indirect
)
diff --git a/libs/go/libp2p_node/go.sum b/libs/go/libp2p_node/go.sum
index 4b233f3a87..cb99823bb5 100644
--- a/libs/go/libp2p_node/go.sum
+++ b/libs/go/libp2p_node/go.sum
@@ -748,6 +748,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs=
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
@@ -781,6 +783,8 @@ golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201215171152-6307297f4651 h1:bdfqbHwYVvhLEIkESR524rqSsmV06Og3Fgz60LE7vZc=
golang.org/x/tools v0.0.0-20201215171152-6307297f4651/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -839,3 +843,5 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.1.4 h1:SadWOkti5uVN1FAMgxn165+Mw00fuQKyk4Gyn/inxNQ=
+honnef.co/go/tools v0.1.4/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
diff --git a/libs/go/libp2p_node/libp2p_node.go b/libs/go/libp2p_node/libp2p_node.go
index c92151c514..f36712df43 100644
--- a/libs/go/libp2p_node/libp2p_node.go
+++ b/libs/go/libp2p_node/libp2p_node.go
@@ -121,6 +121,7 @@ func main() {
opts = append(opts, dhtpeer.EnablePrometheusMonitoring(nodePortMonitoring))
}
if registrationDelay != 0 {
+ //lint:ignore ST1011 don't use unit-specific suffix "Seconds"
durationSeconds := time.Duration(registrationDelay)
opts = append(opts, dhtpeer.WithRegistrationDelay(durationSeconds*1000000*time.Microsecond))
}
diff --git a/libs/go/libp2p_node/utils/utils.go b/libs/go/libp2p_node/utils/utils.go
index 92a01b0648..573ad8f004 100644
--- a/libs/go/libp2p_node/utils/utils.go
+++ b/libs/go/libp2p_node/utils/utils.go
@@ -325,7 +325,7 @@ func VerifyLedgerSignature(
if found {
return verifySignature(message, signature, pubkey)
}
- return false, errors.New("Unsupported ledger")
+ return false, errors.New("unsupported ledger")
}
// VerifyFetchAISignatureBTC verify the RFC6967 string-encoded signature of message using FetchAI public key
@@ -433,7 +433,7 @@ func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string)
}
if recoveredAddress != expectedAddress {
- return false, errors.New("Recovered and expected addresses don't match")
+ return false, errors.New("recovered and expected addresses don't match")
}
return true, nil
@@ -461,7 +461,7 @@ func AgentAddressFromPublicKey(ledgerId string, publicKey string) (string, error
if addressFromPublicKey, found := addressFromPublicKeyTable[ledgerId]; found {
return addressFromPublicKey(publicKey)
}
- return "", errors.New("Unsupported ledger " + ledgerId)
+ return "", errors.New("unsupported ledger " + ledgerId)
}
// FetchAIAddressFromPublicKey get wallet address from hex encoded secp256k1 public key
@@ -639,7 +639,7 @@ func ReadBytesConn(conn net.Conn) ([]byte, error) {
size := binary.BigEndian.Uint32(buf)
if size > maxMessageSizeDelegateConnection {
- return nil, errors.New("Expected message size larger than maximum allowed")
+ return nil, errors.New("expected message size larger than maximum allowed")
}
buf = make([]byte, size)
@@ -670,7 +670,7 @@ func ReadEnvelopeConn(conn net.Conn) (*aea.Envelope, error) {
// ReadBytes from a network stream
func ReadBytes(s network.Stream) ([]byte, error) {
if s == nil {
- panic("GOTCHAAAAAAA 1, can not write to nil stream")
+ panic("CRITICAL can not write to nil stream")
}
rstream := bufio.NewReader(s)
@@ -685,7 +685,7 @@ func ReadBytes(s network.Stream) ([]byte, error) {
size := binary.BigEndian.Uint32(buf)
if size > maxMessageSizeDelegateConnection {
- return nil, errors.New("Expected message size larger than maximum allowed")
+ return nil, errors.New("expected message size larger than maximum allowed")
}
//logger.Debug().Msgf("expecting %d", size)
@@ -707,7 +707,7 @@ func WriteBytes(s network.Stream, data []byte) error {
}
if s == nil {
- panic("GOTCHAAAAAAA 1, can not write to nil stream")
+ panic("CRITICAL, can not write to nil stream")
}
wstream := bufio.NewWriter(s)
@@ -731,7 +731,7 @@ func WriteBytes(s network.Stream, data []byte) error {
return err
}
if s == nil {
- panic("GOTCHAAAAAAA 2, can not write to nil stream")
+ panic("CRITICAL, can not flush nil stream")
}
err = wstream.Flush()
if err != nil {
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index 13bf2ff4b9..716fb33f4e 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -12,31 +12,31 @@ fingerprint:
__init__.py: QmYQuLNyQ8WTjgRYAoKAzoJEb7ocKXvM2hTyK4hsGch5D6
check_dependencies.py: QmP14nkQ8senwzdPdrZJLsA6EQ7zaKKEaLGDELhT42gp1P
connection.py: Qma7YF3frWSKL92FaScmGtR1QmQgvM9QPBdWZPPgHRcTzh
- libp2p_node/README.md: QmSNJEQQwh25QSHgQPM4C84xKU6FczRpmJdN7HkCQyDPuC
+ libp2p_node/README.md: Qmak56XnWfarVxasiaGqYQWJaNVnEAh2hsLWstuFVND98w
libp2p_node/aea/api.go: QmdFR5Rmkk2FGVDwzgHtjobjAKyLejqk2CAYBCvcF23AG7
libp2p_node/aea/envelope.pb.go: QmRfUNGpCeVJfsW3H1MzCN4pwDWgumfyWufVFp6xvUjjug
libp2p_node/aea/envelope.proto: QmVuvesmfgzj5aKnbFoCocoGEv3T9MR7u6KWn7CT5yfjGi
libp2p_node/aea/pipe.go: QmWLBjZNRCcg3BSM9Cxb95yAXdT6wPjgw8DSYHxMuux4JA
- libp2p_node/dht/dhtclient/dhtclient.go: QmYFj4YghhVA7E976xLNQHRTGrik1uHLc6ZQ9Tw1p9ECzk
+ libp2p_node/dht/dhtclient/dhtclient.go: Qmf2x9NZNr7gM1VJfTgzp8Wdjfu2w1krTgLt1PgTgjrY3m
libp2p_node/dht/dhtclient/dhtclient_test.go: QmS9SiLAojXYobqV9m5yeRpyPzt6JcSbQD78RNvSp6LPx6
libp2p_node/dht/dhtclient/options.go: QmaoJiavHescgx98inQjVUipPFRvcFFrodrScZ3fvrXJ4z
libp2p_node/dht/dhtnode/dhtnode.go: QmbyhgbCSAbQ1QsDw7FM7Nt5sZcvhbupA1jv5faxutbV7N
libp2p_node/dht/dhtnode/message.pb.go: QmYT92e2BzAqS4VHmvDeVPs2ymToysmT9rtfwMBMtRg8nn
libp2p_node/dht/dhtnode/message.proto: QmbgFcGVbxx4CP53cefW7JhXLYha6meSYqZ9hZJgBpcinF
libp2p_node/dht/dhtnode/streams.go: Qmc2JcyiU4wHsgDj6aUunMAp4c5yMzo2ixeqRZHSW5PVwo
- libp2p_node/dht/dhtnode/utils.go: QmcHGWgCXh1mtZCL9S9yQ2qjgKB2AbsYiG5sajrSBjCGuF
+ libp2p_node/dht/dhtnode/utils.go: QmcSEvmhU5TwL92qB1Nu3E28Lhs6UZ1GRnHwQ9knMdiyGx
libp2p_node/dht/dhtpeer/benchmarks_test.go: QmX2KWsaFaVd9KGjvgYNgkLtgnu1CUhBPtTe9abKYndq4C
- libp2p_node/dht/dhtpeer/dhtpeer.go: QmUrp42Kty9Rt4p2hY3FutRMNKKdRXQGjGBoSd1YiSsAaH
- libp2p_node/dht/dhtpeer/dhtpeer_test.go: QmXySdeKevKC6jWweDX77ncGA1G5nyYNyfTgFB4S1y4kw8
+ libp2p_node/dht/dhtpeer/dhtpeer.go: QmUS4bDXngfGL5X4CTPbb7qk2uN9rc2txerqdAuEi2QKQg
+ libp2p_node/dht/dhtpeer/dhtpeer_test.go: QmT8KpPtxwAFA9rHLJjh4wboGQ7bmLGFowQ2U94adzhWUL
libp2p_node/dht/dhtpeer/options.go: QmRbB1dnA5TEeJZQpKBJQoxFNHSPLRiEtwtkK6ZJDZdjAX
libp2p_node/dht/dhttests/dhttests.go: QmWTwAqXy4xPBWx49dvg91pBfaeyh79bgbh4yYc3u6kGhg
- libp2p_node/dht/monitoring/file.go: QmfSw8prwiuxqcaTrEkWAL4dZYi7EzWGA4ZCgPgQ99ZnGN
+ libp2p_node/dht/monitoring/file.go: Qmb8U557xYB3gA3xRXSsjtZNTn5Cyn6VyHhDEseFfHpuTL
libp2p_node/dht/monitoring/prometheus.go: QmQvXjEozVPMvRjda5WGRAU5b7cfUcRZUACQkTESG7Aewu
libp2p_node/dht/monitoring/service.go: QmT47y2LHZECYcoE2uJ9QCGh3Kq8ePhYedo8dQE7X7v6YV
- libp2p_node/go.mod: QmT2LQXkSen6Th4QLS2RU3tRVxJSLjdZTxRULUcnQFXfEL
- libp2p_node/go.sum: QmZc6oiDqQhB6ZKVojN26JxoTNH1QetyuYd9zjSksQnTFt
- libp2p_node/libp2p_node.go: QmSu21WBmAAfBbZFi3MZZgTrUMK5FYruSunxghpeUhxBMA
- libp2p_node/utils/utils.go: QmYKmPHnv9RHzw1XbyBvTN57jPojxGiTM3v23rdKxKFW2R
+ libp2p_node/go.mod: QmU2MJhhvwTCfyztCei5R9LKStadFuFVUDb16s3tZwrZP8
+ libp2p_node/go.sum: QmVpr925Kp8ZS7Z1iLfbjDB6NxG5BA7JczhhckzhmbYqzT
+ libp2p_node/libp2p_node.go: QmPgMQ3g93Jqu4GAv8e7fTWbrGK8hjSp7BDrKj1EuR1WcS
+ libp2p_node/utils/utils.go: QmUSw5SD3i7WhkPCVHc5ha6BhJbzk4Cf8HbyysEwUVz5zt
fingerprint_ignore_patterns: []
build_entrypoint: check_dependencies.py
connections: []
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/README.md b/packages/fetchai/connections/p2p_libp2p/libp2p_node/README.md
index d95ba19985..0d084a56dd 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/README.md
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/README.md
@@ -20,6 +20,7 @@ To lint:
``` bash
golines . -w
golangci-lint run
+staticcheck ./...
```
## Messaging patterns
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtclient/dhtclient.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtclient/dhtclient.go
index e627a21684..e9f6278e27 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtclient/dhtclient.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtclient/dhtclient.go
@@ -306,7 +306,6 @@ func (dhtClient *DHTClient) bootstrapLoopUntilTimeout() error {
)
case <-ctx.Done():
sleepTime = 0
- break
}
if sleepTime == 0 {
break
@@ -338,12 +337,14 @@ func (dhtClient *DHTClient) newStreamLoopUntilTimeout(
stream, err = dhtClient.routedHost.NewStream(ctx, peerID, streamType)
case <-ctx.Done():
sleepTime = 0
- break
}
if sleepTime == 0 {
break
}
}
+ if stream == nil {
+ return stream, errors.New("stream nil" + err.Error())
+ }
// register again in case of disconnection
if disconnected {
err = dhtClient.registerAgentAddress()
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtnode/utils.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtnode/utils.go
index bdd237a75b..acf9781075 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtnode/utils.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtnode/utils.go
@@ -67,7 +67,7 @@ func IsValidProofOfRepresentation(
// check public key matches
if record.PeerPublicKey != representativePeerPubKey {
- err := errors.New("Wrong peer public key, expected " + representativePeerPubKey)
+ err := errors.New("wrong peer public key, expected " + representativePeerPubKey)
response := &Status{Code: Status_ERROR_WRONG_PUBLIC_KEY, Msgs: []string{err.Error()}}
return response, err
}
@@ -76,7 +76,7 @@ func IsValidProofOfRepresentation(
addrFromPubKey, err := utils.AgentAddressFromPublicKey(record.LedgerId, record.PublicKey)
if err != nil || addrFromPubKey != record.Address {
if err == nil {
- err = errors.New("Agent address and public key don't match")
+ err = errors.New("agent address and public key don't match")
}
response := &Status{Code: Status_ERROR_WRONG_AGENT_ADDRESS}
return response, err
@@ -91,7 +91,7 @@ func IsValidProofOfRepresentation(
)
if !ok || err != nil {
if err == nil {
- err = errors.New("Signature is not valid")
+ err = errors.New("signature is not valid")
}
response := &Status{Code: Status_ERROR_INVALID_PROOF}
return response, err
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer.go
index f562cd3859..13b8bb4ca5 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer.go
@@ -629,7 +629,6 @@ func (dhtPeer *DHTPeer) handleDelegateService(ready *sync.WaitGroup) {
go dhtPeer.handleNewDelegationConnection(conn)
}
case <-dhtPeer.closing:
- break
}
}
}
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go
index d7686e3e4d..07705ca253 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go
@@ -1959,7 +1959,6 @@ func ensureAddressAnnounced(peers ...*DHTPeer) {
for !peer.addressAnnounced {
select {
case <-ctx.Done():
- break
case <-time.After(5 * time.Millisecond):
}
}
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/monitoring/file.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/monitoring/file.go
index 7c8248db77..ca2b39d591 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/monitoring/file.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/monitoring/file.go
@@ -176,7 +176,6 @@ func (fm *FileMonitoring) Start() {
select {
case <-fm.closing:
file.Close()
- break
default:
ignore(file.Truncate(0))
_, err := file.Seek(0, 0)
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.mod b/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.mod
index e06f56bec4..a5d16c054d 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.mod
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.mod
@@ -27,8 +27,7 @@ require (
github.com/sirupsen/logrus v1.7.0 // indirect
golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9
golang.org/x/mod v0.4.0 // indirect
- golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
- golang.org/x/tools v0.0.0-20201215171152-6307297f4651 // indirect
google.golang.org/protobuf v1.25.0
+ honnef.co/go/tools v0.1.4 // indirect
)
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.sum b/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.sum
index 4b233f3a87..cb99823bb5 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.sum
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.sum
@@ -748,6 +748,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e h1:AyodaIpKjppX+cBfTASF2E1US3H2JFBj920Ot3rtDjs=
golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
+golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
@@ -781,6 +783,8 @@ golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201215171152-6307297f4651 h1:bdfqbHwYVvhLEIkESR524rqSsmV06Og3Fgz60LE7vZc=
golang.org/x/tools v0.0.0-20201215171152-6307297f4651/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
+golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -839,3 +843,5 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.1.4 h1:SadWOkti5uVN1FAMgxn165+Mw00fuQKyk4Gyn/inxNQ=
+honnef.co/go/tools v0.1.4/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/libp2p_node.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/libp2p_node.go
index c92151c514..f36712df43 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/libp2p_node.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/libp2p_node.go
@@ -121,6 +121,7 @@ func main() {
opts = append(opts, dhtpeer.EnablePrometheusMonitoring(nodePortMonitoring))
}
if registrationDelay != 0 {
+ //lint:ignore ST1011 don't use unit-specific suffix "Seconds"
durationSeconds := time.Duration(registrationDelay)
opts = append(opts, dhtpeer.WithRegistrationDelay(durationSeconds*1000000*time.Microsecond))
}
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
index 92a01b0648..573ad8f004 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
@@ -325,7 +325,7 @@ func VerifyLedgerSignature(
if found {
return verifySignature(message, signature, pubkey)
}
- return false, errors.New("Unsupported ledger")
+ return false, errors.New("unsupported ledger")
}
// VerifyFetchAISignatureBTC verify the RFC6967 string-encoded signature of message using FetchAI public key
@@ -433,7 +433,7 @@ func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string)
}
if recoveredAddress != expectedAddress {
- return false, errors.New("Recovered and expected addresses don't match")
+ return false, errors.New("recovered and expected addresses don't match")
}
return true, nil
@@ -461,7 +461,7 @@ func AgentAddressFromPublicKey(ledgerId string, publicKey string) (string, error
if addressFromPublicKey, found := addressFromPublicKeyTable[ledgerId]; found {
return addressFromPublicKey(publicKey)
}
- return "", errors.New("Unsupported ledger " + ledgerId)
+ return "", errors.New("unsupported ledger " + ledgerId)
}
// FetchAIAddressFromPublicKey get wallet address from hex encoded secp256k1 public key
@@ -639,7 +639,7 @@ func ReadBytesConn(conn net.Conn) ([]byte, error) {
size := binary.BigEndian.Uint32(buf)
if size > maxMessageSizeDelegateConnection {
- return nil, errors.New("Expected message size larger than maximum allowed")
+ return nil, errors.New("expected message size larger than maximum allowed")
}
buf = make([]byte, size)
@@ -670,7 +670,7 @@ func ReadEnvelopeConn(conn net.Conn) (*aea.Envelope, error) {
// ReadBytes from a network stream
func ReadBytes(s network.Stream) ([]byte, error) {
if s == nil {
- panic("GOTCHAAAAAAA 1, can not write to nil stream")
+ panic("CRITICAL can not write to nil stream")
}
rstream := bufio.NewReader(s)
@@ -685,7 +685,7 @@ func ReadBytes(s network.Stream) ([]byte, error) {
size := binary.BigEndian.Uint32(buf)
if size > maxMessageSizeDelegateConnection {
- return nil, errors.New("Expected message size larger than maximum allowed")
+ return nil, errors.New("expected message size larger than maximum allowed")
}
//logger.Debug().Msgf("expecting %d", size)
@@ -707,7 +707,7 @@ func WriteBytes(s network.Stream, data []byte) error {
}
if s == nil {
- panic("GOTCHAAAAAAA 1, can not write to nil stream")
+ panic("CRITICAL, can not write to nil stream")
}
wstream := bufio.NewWriter(s)
@@ -731,7 +731,7 @@ func WriteBytes(s network.Stream, data []byte) error {
return err
}
if s == nil {
- panic("GOTCHAAAAAAA 2, can not write to nil stream")
+ panic("CRITICAL, can not flush nil stream")
}
err = wstream.Flush()
if err != nil {
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 9ca813ca11..13bcfabc3c 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmZ2BpAKYyuRno8diqN8sbWEzHkjnWgLGg2kWbcEDdWkEi
+fetchai/connections/p2p_libp2p,QmZLQXjJT2kFEDjrGHquBzAAWactzhRxPQjhZfocTXhf27
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
From 516b1988d89c141b3090e3014ceb9438a37969a1 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Fri, 7 May 2021 13:04:10 +0100
Subject: [PATCH 012/147] fix: break implemented properly
---
examples/tac_deploy/entrypoint.sh | 4 +++-
libs/go/libp2p_node/dht/dhtclient/dhtclient.go | 14 ++++----------
libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go | 2 ++
libs/go/libp2p_node/dht/monitoring/file.go | 2 ++
.../fetchai/connections/p2p_libp2p/connection.yaml | 6 +++---
.../libp2p_node/dht/dhtclient/dhtclient.go | 14 ++++----------
.../libp2p_node/dht/dhtpeer/dhtpeer_test.go | 2 ++
.../p2p_libp2p/libp2p_node/dht/monitoring/file.go | 2 ++
packages/hashes.csv | 2 +-
9 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/examples/tac_deploy/entrypoint.sh b/examples/tac_deploy/entrypoint.sh
index c30f46dea9..fcd5460d8a 100755
--- a/examples/tac_deploy/entrypoint.sh
+++ b/examples/tac_deploy/entrypoint.sh
@@ -3,7 +3,8 @@ set -e
LEDGER=fetchai
PEER="/dns4/acn.fetch.ai/tcp/9001/p2p/16Uiu2HAmVWnopQAqq4pniYLw44VRvYxBUoRHqjz1Hh2SoCyjbyRW"
-TAC_NAME='some_tac_id'
+TAC_NAME='v'$((10 + $RANDOM % 1000))
+TAC_SERVICE=tac_service_$TAC_NAME
BASE_PORT=10000
BASE_DIR=/data
OLD_DIR=/$(date "+%d_%m_%Y_%H%M")
@@ -148,6 +149,7 @@ function set_participant(){
set_agent $agent_name $(expr $BASE_PORT + $agent_id)
aea config set vendor.fetchai.skills.tac_negotiation.behaviours.clean_up.args.tick_interval $CLEANUP_INTERVAL
aea config set vendor.fetchai.skills.tac_negotiation.behaviours.tac_negotiation.args.search_interval $SEARCH_INTERVAL_TRADING
+ aea config set vendor.fetchai.skills.tac_negotiation.models.strategy.args.service_key $TAC_SERVICE
aea config set vendor.fetchai.skills.tac_participation.behaviours.tac_search.args.tick_interval $SEARCH_INTERVAL_GAME
aea config set vendor.fetchai.skills.tac_participation.models.game.args.search_query.search_value $TAC_NAME
cd ..
diff --git a/libs/go/libp2p_node/dht/dhtclient/dhtclient.go b/libs/go/libp2p_node/dht/dhtclient/dhtclient.go
index e9f6278e27..9c69206ea9 100644
--- a/libs/go/libp2p_node/dht/dhtclient/dhtclient.go
+++ b/libs/go/libp2p_node/dht/dhtclient/dhtclient.go
@@ -305,10 +305,7 @@ func (dhtClient *DHTClient) bootstrapLoopUntilTimeout() error {
dhtClient.bootstrapPeers,
)
case <-ctx.Done():
- sleepTime = 0
- }
- if sleepTime == 0 {
- break
+ err = errors.New("bootstrap connect timeout reached")
}
}
return err
@@ -336,14 +333,11 @@ func (dhtClient *DHTClient) newStreamLoopUntilTimeout(
sleepTime = sleepTime * sleepTimeIncreaseMFactor
stream, err = dhtClient.routedHost.NewStream(ctx, peerID, streamType)
case <-ctx.Done():
- sleepTime = 0
- }
- if sleepTime == 0 {
- break
+ err = errors.New("new stream loop timeout reached")
}
}
- if stream == nil {
- return stream, errors.New("stream nil" + err.Error())
+ if stream == nil && err == nil {
+ return nil, errors.New("stream nil and err nil")
}
// register again in case of disconnection
if disconnected {
diff --git a/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go b/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go
index 07705ca253..8aaf6ce8c8 100644
--- a/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go
+++ b/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go
@@ -1956,9 +1956,11 @@ func ensureAddressAnnounced(peers ...*DHTPeer) {
for _, peer := range peers {
ctx, cancel := context.WithTimeout(context.Background(), DHTPeerSetupTimeout)
defer cancel()
+ L:
for !peer.addressAnnounced {
select {
case <-ctx.Done():
+ break L
case <-time.After(5 * time.Millisecond):
}
}
diff --git a/libs/go/libp2p_node/dht/monitoring/file.go b/libs/go/libp2p_node/dht/monitoring/file.go
index ca2b39d591..2bd027110f 100644
--- a/libs/go/libp2p_node/dht/monitoring/file.go
+++ b/libs/go/libp2p_node/dht/monitoring/file.go
@@ -172,10 +172,12 @@ func (fm *FileMonitoring) Start() {
fm.closing = make(chan struct{})
file, _ := os.OpenFile(fm.path, os.O_WRONLY|os.O_CREATE, 0666)
+L:
for {
select {
case <-fm.closing:
file.Close()
+ break L
default:
ignore(file.Truncate(0))
_, err := file.Seek(0, 0)
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index 716fb33f4e..426b25b37b 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -17,7 +17,7 @@ fingerprint:
libp2p_node/aea/envelope.pb.go: QmRfUNGpCeVJfsW3H1MzCN4pwDWgumfyWufVFp6xvUjjug
libp2p_node/aea/envelope.proto: QmVuvesmfgzj5aKnbFoCocoGEv3T9MR7u6KWn7CT5yfjGi
libp2p_node/aea/pipe.go: QmWLBjZNRCcg3BSM9Cxb95yAXdT6wPjgw8DSYHxMuux4JA
- libp2p_node/dht/dhtclient/dhtclient.go: Qmf2x9NZNr7gM1VJfTgzp8Wdjfu2w1krTgLt1PgTgjrY3m
+ libp2p_node/dht/dhtclient/dhtclient.go: QmQpfFiHT7vwrdt6o7EuzgAbweXzP5rpndUiD3UAH2Naw7
libp2p_node/dht/dhtclient/dhtclient_test.go: QmS9SiLAojXYobqV9m5yeRpyPzt6JcSbQD78RNvSp6LPx6
libp2p_node/dht/dhtclient/options.go: QmaoJiavHescgx98inQjVUipPFRvcFFrodrScZ3fvrXJ4z
libp2p_node/dht/dhtnode/dhtnode.go: QmbyhgbCSAbQ1QsDw7FM7Nt5sZcvhbupA1jv5faxutbV7N
@@ -27,10 +27,10 @@ fingerprint:
libp2p_node/dht/dhtnode/utils.go: QmcSEvmhU5TwL92qB1Nu3E28Lhs6UZ1GRnHwQ9knMdiyGx
libp2p_node/dht/dhtpeer/benchmarks_test.go: QmX2KWsaFaVd9KGjvgYNgkLtgnu1CUhBPtTe9abKYndq4C
libp2p_node/dht/dhtpeer/dhtpeer.go: QmUS4bDXngfGL5X4CTPbb7qk2uN9rc2txerqdAuEi2QKQg
- libp2p_node/dht/dhtpeer/dhtpeer_test.go: QmT8KpPtxwAFA9rHLJjh4wboGQ7bmLGFowQ2U94adzhWUL
+ libp2p_node/dht/dhtpeer/dhtpeer_test.go: QmbygeomT8dmpo6qbj1VyqMujgqfnmvN9kbQKYh77HcvdK
libp2p_node/dht/dhtpeer/options.go: QmRbB1dnA5TEeJZQpKBJQoxFNHSPLRiEtwtkK6ZJDZdjAX
libp2p_node/dht/dhttests/dhttests.go: QmWTwAqXy4xPBWx49dvg91pBfaeyh79bgbh4yYc3u6kGhg
- libp2p_node/dht/monitoring/file.go: Qmb8U557xYB3gA3xRXSsjtZNTn5Cyn6VyHhDEseFfHpuTL
+ libp2p_node/dht/monitoring/file.go: Qmc4QpKtjXaEFqGPeunV6TR4qR5RcMzoy8atzJH4ouBkfH
libp2p_node/dht/monitoring/prometheus.go: QmQvXjEozVPMvRjda5WGRAU5b7cfUcRZUACQkTESG7Aewu
libp2p_node/dht/monitoring/service.go: QmT47y2LHZECYcoE2uJ9QCGh3Kq8ePhYedo8dQE7X7v6YV
libp2p_node/go.mod: QmU2MJhhvwTCfyztCei5R9LKStadFuFVUDb16s3tZwrZP8
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtclient/dhtclient.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtclient/dhtclient.go
index e9f6278e27..9c69206ea9 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtclient/dhtclient.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtclient/dhtclient.go
@@ -305,10 +305,7 @@ func (dhtClient *DHTClient) bootstrapLoopUntilTimeout() error {
dhtClient.bootstrapPeers,
)
case <-ctx.Done():
- sleepTime = 0
- }
- if sleepTime == 0 {
- break
+ err = errors.New("bootstrap connect timeout reached")
}
}
return err
@@ -336,14 +333,11 @@ func (dhtClient *DHTClient) newStreamLoopUntilTimeout(
sleepTime = sleepTime * sleepTimeIncreaseMFactor
stream, err = dhtClient.routedHost.NewStream(ctx, peerID, streamType)
case <-ctx.Done():
- sleepTime = 0
- }
- if sleepTime == 0 {
- break
+ err = errors.New("new stream loop timeout reached")
}
}
- if stream == nil {
- return stream, errors.New("stream nil" + err.Error())
+ if stream == nil && err == nil {
+ return nil, errors.New("stream nil and err nil")
}
// register again in case of disconnection
if disconnected {
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go
index 07705ca253..8aaf6ce8c8 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go
@@ -1956,9 +1956,11 @@ func ensureAddressAnnounced(peers ...*DHTPeer) {
for _, peer := range peers {
ctx, cancel := context.WithTimeout(context.Background(), DHTPeerSetupTimeout)
defer cancel()
+ L:
for !peer.addressAnnounced {
select {
case <-ctx.Done():
+ break L
case <-time.After(5 * time.Millisecond):
}
}
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/monitoring/file.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/monitoring/file.go
index ca2b39d591..2bd027110f 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/monitoring/file.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/monitoring/file.go
@@ -172,10 +172,12 @@ func (fm *FileMonitoring) Start() {
fm.closing = make(chan struct{})
file, _ := os.OpenFile(fm.path, os.O_WRONLY|os.O_CREATE, 0666)
+L:
for {
select {
case <-fm.closing:
file.Close()
+ break L
default:
ignore(file.Truncate(0))
_, err := file.Seek(0, 0)
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 13bcfabc3c..800564ab3e 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmZLQXjJT2kFEDjrGHquBzAAWactzhRxPQjhZfocTXhf27
+fetchai/connections/p2p_libp2p,QmScRjUdhfd6KnYXErToUExaQEcJFfhRHDWzPSiN6eD69n
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
From 182b96bdec241f1ff8d18d33b533eca5886a024b Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Fri, 7 May 2021 13:19:22 +0100
Subject: [PATCH 013/147] feat: fix missing break statement
---
libs/go/libp2p_node/dht/dhtpeer/dhtpeer.go | 2 ++
packages/fetchai/connections/p2p_libp2p/connection.yaml | 2 +-
.../connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer.go | 2 ++
packages/hashes.csv | 2 +-
4 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/libs/go/libp2p_node/dht/dhtpeer/dhtpeer.go b/libs/go/libp2p_node/dht/dhtpeer/dhtpeer.go
index 13b8bb4ca5..044b59beca 100644
--- a/libs/go/libp2p_node/dht/dhtpeer/dhtpeer.go
+++ b/libs/go/libp2p_node/dht/dhtpeer/dhtpeer.go
@@ -607,6 +607,7 @@ func (dhtPeer *DHTPeer) handleDelegateService(ready *sync.WaitGroup) {
lerror, _, linfo, _ := dhtPeer.getLoggers()
done := false
+L:
for {
select {
default:
@@ -629,6 +630,7 @@ func (dhtPeer *DHTPeer) handleDelegateService(ready *sync.WaitGroup) {
go dhtPeer.handleNewDelegationConnection(conn)
}
case <-dhtPeer.closing:
+ break L
}
}
}
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index 426b25b37b..5ef391e165 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -26,7 +26,7 @@ fingerprint:
libp2p_node/dht/dhtnode/streams.go: Qmc2JcyiU4wHsgDj6aUunMAp4c5yMzo2ixeqRZHSW5PVwo
libp2p_node/dht/dhtnode/utils.go: QmcSEvmhU5TwL92qB1Nu3E28Lhs6UZ1GRnHwQ9knMdiyGx
libp2p_node/dht/dhtpeer/benchmarks_test.go: QmX2KWsaFaVd9KGjvgYNgkLtgnu1CUhBPtTe9abKYndq4C
- libp2p_node/dht/dhtpeer/dhtpeer.go: QmUS4bDXngfGL5X4CTPbb7qk2uN9rc2txerqdAuEi2QKQg
+ libp2p_node/dht/dhtpeer/dhtpeer.go: Qmd5nq6uhStQwsoYNrWwguY1xDY3Ako6gExjFsBC7E2nse
libp2p_node/dht/dhtpeer/dhtpeer_test.go: QmbygeomT8dmpo6qbj1VyqMujgqfnmvN9kbQKYh77HcvdK
libp2p_node/dht/dhtpeer/options.go: QmRbB1dnA5TEeJZQpKBJQoxFNHSPLRiEtwtkK6ZJDZdjAX
libp2p_node/dht/dhttests/dhttests.go: QmWTwAqXy4xPBWx49dvg91pBfaeyh79bgbh4yYc3u6kGhg
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer.go
index 13b8bb4ca5..044b59beca 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer.go
@@ -607,6 +607,7 @@ func (dhtPeer *DHTPeer) handleDelegateService(ready *sync.WaitGroup) {
lerror, _, linfo, _ := dhtPeer.getLoggers()
done := false
+L:
for {
select {
default:
@@ -629,6 +630,7 @@ func (dhtPeer *DHTPeer) handleDelegateService(ready *sync.WaitGroup) {
go dhtPeer.handleNewDelegationConnection(conn)
}
case <-dhtPeer.closing:
+ break L
}
}
}
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 800564ab3e..71404119ae 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmScRjUdhfd6KnYXErToUExaQEcJFfhRHDWzPSiN6eD69n
+fetchai/connections/p2p_libp2p,QmRip7XE3n4vpCSEShuGyQDNZz7AuJFbKvc3HSNEzEqV9a
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
From f28661a97b44456b0d1194b890ca64e46a52f853 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Fri, 7 May 2021 14:30:33 +0100
Subject: [PATCH 014/147] feat: add resource spec for tac deploy
fix: overlap in tac identifiers
---
examples/tac_deploy/tac-deployment.yaml | 7 +++++++
.../test_packages/test_skills_integration/test_tac.py | 10 ++++++++++
2 files changed, 17 insertions(+)
diff --git a/examples/tac_deploy/tac-deployment.yaml b/examples/tac_deploy/tac-deployment.yaml
index 8b82f70e63..4c309932db 100644
--- a/examples/tac_deploy/tac-deployment.yaml
+++ b/examples/tac_deploy/tac-deployment.yaml
@@ -19,6 +19,13 @@ spec:
containers:
- name: tac-deploy-container
image: gcr.io/fetch-ai-sandbox/tac_deploy:0.0.13
+ resources:
+ requests:
+ memory: "12000000Ki"
+ cpu: "3700m"
+ limits:
+ memory: "12000000Ki"
+ cpu: "3700m"
env:
- name: PARTICIPANTS_AMOUNT
value: "70"
diff --git a/tests/test_packages/test_skills_integration/test_tac.py b/tests/test_packages/test_skills_integration/test_tac.py
index 41e2ad626f..92350a0eb5 100644
--- a/tests/test_packages/test_skills_integration/test_tac.py
+++ b/tests/test_packages/test_skills_integration/test_tac.py
@@ -82,6 +82,7 @@ def test_tac(self):
# tac name
tac_id = uuid.uuid4().hex
+ tac_service = f"tac_service_{tac_id}"
# prepare tac controller for test
self.set_agent_context(tac_controller_name)
@@ -203,6 +204,10 @@ def test_tac(self):
"vendor.fetchai.skills.tac_participation.models.game.args.search_query"
)
self.nested_set_config(setting_path, data)
+ self.set_config(
+ "vendor.fetchai.skills.tac_negotiation.models.strategy.args.service_key",
+ tac_service,
+ )
self.run_cli_command("build", cwd=self._get_cwd())
self.run_cli_command("issue-certificates", cwd=self._get_cwd())
@@ -356,6 +361,7 @@ def test_tac(self):
# tac name
tac_id = uuid.uuid4().hex
+ tac_service = f"tac_service_{tac_id}"
# prepare tac controller for test
self.set_agent_context(tac_controller_name)
@@ -538,6 +544,10 @@ def test_tac(self):
), "Difference between created and fetched project for files={}".format(
diff
)
+ self.set_config(
+ "vendor.fetchai.skills.tac_negotiation.models.strategy.args.service_key",
+ tac_service,
+ )
# run tac controller
self.set_agent_context(tac_controller_name)
From e59b8da4b4a1f0951442c34c990fb79f784d1f50 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Fri, 7 May 2021 15:17:45 +0100
Subject: [PATCH 015/147] fix: missing await keyword
---
packages/fetchai/connections/p2p_libp2p/connection.py | 2 +-
packages/fetchai/connections/p2p_libp2p/connection.yaml | 2 +-
packages/hashes.csv | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.py b/packages/fetchai/connections/p2p_libp2p/connection.py
index 32ec7eb3b1..c240de23ae 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.py
+++ b/packages/fetchai/connections/p2p_libp2p/connection.py
@@ -803,7 +803,7 @@ async def _read_envelope_from_node(self) -> Optional[Envelope]:
f"Failed to read. Exception: {e}. Try reconnect to node and read again."
)
- self._restart_node()
+ await self._restart_node()
return await self._node_client.read_envelope()
async def _receive_from_node(self) -> None:
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index 5ef391e165..aae241665d 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -11,7 +11,7 @@ fingerprint:
README.md: QmWcd2zHiRZLgXCSGw9gZ35WfcKsMeNSQouqNAaZnPBDDR
__init__.py: QmYQuLNyQ8WTjgRYAoKAzoJEb7ocKXvM2hTyK4hsGch5D6
check_dependencies.py: QmP14nkQ8senwzdPdrZJLsA6EQ7zaKKEaLGDELhT42gp1P
- connection.py: Qma7YF3frWSKL92FaScmGtR1QmQgvM9QPBdWZPPgHRcTzh
+ connection.py: QmXmCBy8AizGefC8JJo2nJZySY2kmevNgxxgMkJPvoNQRR
libp2p_node/README.md: Qmak56XnWfarVxasiaGqYQWJaNVnEAh2hsLWstuFVND98w
libp2p_node/aea/api.go: QmdFR5Rmkk2FGVDwzgHtjobjAKyLejqk2CAYBCvcF23AG7
libp2p_node/aea/envelope.pb.go: QmRfUNGpCeVJfsW3H1MzCN4pwDWgumfyWufVFp6xvUjjug
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 71404119ae..84274a556f 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmRip7XE3n4vpCSEShuGyQDNZz7AuJFbKvc3HSNEzEqV9a
+fetchai/connections/p2p_libp2p,QmQ1FBNQezRPufMZDyVcW4KuADyKPQHb2Xo4qtLFcTgmAD
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
From ea0c2b68a1c5713b03725a9de9a14088f74c36f9 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Fri, 7 May 2021 17:56:53 +0300
Subject: [PATCH 016/147] USE_CLIENT fix
---
examples/tac_deploy/entrypoint.sh | 2 +-
examples/tac_deploy/tac-deployment.yaml | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/examples/tac_deploy/entrypoint.sh b/examples/tac_deploy/entrypoint.sh
index fcd5460d8a..b04ed0248f 100755
--- a/examples/tac_deploy/entrypoint.sh
+++ b/examples/tac_deploy/entrypoint.sh
@@ -118,7 +118,7 @@ function set_agent(){
aea add-key fetchai $key_file_name
key_file_name=$(generate_key $LEDGER $name $agent_data_dir 1)
aea add-key fetchai $key_file_name --connection
- if [ "$USE_CLIENT" == false ];
+ if [ "$USE_CLIENT" == "false" ];
then
json=$(printf '{"log_file": "%s", "delegate_uri": null, "entry_peers": ["%s"], "local_uri": "127.0.0.1:%s", "public_uri": null, "node_connection_timeout": '%i'}' "$agent_data_dir/libp2p_node.log" "$PEER" "$port" "$(($NODE_CONNECTION_TIMEOUT))")
aea config set --type dict vendor.fetchai.connections.p2p_libp2p.config "$json"
diff --git a/examples/tac_deploy/tac-deployment.yaml b/examples/tac_deploy/tac-deployment.yaml
index 8b82f70e63..9004acfcef 100644
--- a/examples/tac_deploy/tac-deployment.yaml
+++ b/examples/tac_deploy/tac-deployment.yaml
@@ -42,6 +42,8 @@ spec:
value: "true"
- name: CLEAR_KEY_DATA_ON_LAUNCH
value: "true"
+ - name: USE_CLIENT
+ value: "false"
volumeMounts:
- name: tac-deploy-data-vol
mountPath: /data
From 0b78f868a607614e9b86f590f19723be1616480d Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Fri, 7 May 2021 18:02:15 +0300
Subject: [PATCH 017/147] use_client default value
---
examples/tac_deploy/entrypoint.sh | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/examples/tac_deploy/entrypoint.sh b/examples/tac_deploy/entrypoint.sh
index b04ed0248f..8c554fc302 100755
--- a/examples/tac_deploy/entrypoint.sh
+++ b/examples/tac_deploy/entrypoint.sh
@@ -86,6 +86,10 @@ if [ "$CLEAR_KEY_DATA_ON_LAUNCH" == true ]; then
find "$BASE_DIR" -name \*.txt -type f -delete
fi
+if [ -z "$USE_CLIENT" ]; then
+ USE_CLIENT=false
+fi
+
function generate_key (){
ledger=$1
prefix=$2
From 2735bf8bd32e6f3ae0ead666f5889eafd0bf879d Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 10 May 2021 11:57:54 +0300
Subject: [PATCH 018/147] small fixes for str formatting
---
plugins/aea-ledger-ethereum/tests/docker_image.py | 2 +-
tests/common/docker_image.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/plugins/aea-ledger-ethereum/tests/docker_image.py b/plugins/aea-ledger-ethereum/tests/docker_image.py
index ce8f63538d..5ee0ccb0c7 100644
--- a/plugins/aea-ledger-ethereum/tests/docker_image.py
+++ b/plugins/aea-ledger-ethereum/tests/docker_image.py
@@ -72,7 +72,7 @@ def _check_docker_binary_available(self):
result.stdout.decode("utf-8"),
)
if match is None:
- pytest.skip(f"cannot read version from the output of 'docker --version'")
+ pytest.skip("cannot read version from the output of 'docker --version'")
version = (int(match.group(1)), int(match.group(2)), int(match.group(3)))
if version < self.MINIMUM_DOCKER_VERSION:
pytest.skip(
diff --git a/tests/common/docker_image.py b/tests/common/docker_image.py
index 7e08bb5bd6..2c35b780de 100644
--- a/tests/common/docker_image.py
+++ b/tests/common/docker_image.py
@@ -79,7 +79,7 @@ def _check_docker_binary_available(self):
result.stdout.decode("utf-8"),
)
if match is None:
- pytest.skip(f"cannot read version from the output of 'docker --version'")
+ pytest.skip("cannot read version from the output of 'docker --version'")
version = (int(match.group(1)), int(match.group(2)), int(match.group(3)))
if version < self.MINIMUM_DOCKER_VERSION:
pytest.skip(
From 0aa942f4ad4b165c8658d5435f4f756ce91cd101 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 10 May 2021 12:01:16 +0300
Subject: [PATCH 019/147] p2p libp2p connection send envelope queue
---
.../connections/p2p_libp2p/connection.py | 47 +++++++++++++++----
.../connections/p2p_libp2p/connection.yaml | 2 +-
packages/hashes.csv | 2 +-
.../test_p2p_libp2p/test_errors.py | 2 +-
4 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.py b/packages/fetchai/connections/p2p_libp2p/connection.py
index c240de23ae..af53df2914 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.py
+++ b/packages/fetchai/connections/p2p_libp2p/connection.py
@@ -681,6 +681,9 @@ def __init__(self, **kwargs: Any) -> None:
self._receive_from_node_task = None # type: Optional[asyncio.Future]
self._node_client: Optional[NodeClient] = None
+ self._send_queue: Optional[asyncio.Queue] = None
+ self._send_task: Optional[asyncio.Task] = None
+
def _check_node_built(self) -> str:
"""Check node built."""
if self.configuration.build_directory is None:
@@ -710,9 +713,11 @@ async def connect(self) -> None:
await self._start_node()
# starting receiving msgs
self._in_queue = asyncio.Queue()
+ self._send_queue = asyncio.Queue()
self._receive_from_node_task = asyncio.ensure_future(
self._receive_from_node(), loop=self.loop
)
+ self._send_task = self.loop.create_task(self._send_loop())
self.state = ConnectionStates.connected
except (CancelledError, Exception) as e:
self.state = ConnectionStates.disconnected
@@ -736,10 +741,17 @@ async def disconnect(self) -> None:
"""
if self.is_disconnected:
return # pragma: nocover
+
self.state = ConnectionStates.disconnecting
+
if self._receive_from_node_task is not None:
self._receive_from_node_task.cancel()
self._receive_from_node_task = None
+
+ if self._send_task is not None:
+ self._send_task.cancel()
+ self._send_task = None
+
await self.node.stop()
if self._in_queue is not None:
self._in_queue.put_nowait(None)
@@ -770,16 +782,10 @@ async def receive(self, *args: Any, **kwargs: Any) -> Optional["Envelope"]:
self.logger.exception(e)
return None
- async def send(self, envelope: Envelope) -> None:
- """
- Send messages.
-
- :return: None
- """
- if not self._node_client:
- raise ValueError("Node is not connected!") # pragma: nocover
+ async def _send_envelope_with_node_client(self, envelope: Envelope) -> None:
+ if not self._node_client: # pragma: nocover
+ raise ValueError(f"Node client not set! Can not send envelope: {envelope}")
- self._ensure_valid_envelope_for_external_comms(envelope)
try:
await self._node_client.send_envelope(envelope)
except asyncio.CancelledError: # pylint: disable=try-except-raise
@@ -791,6 +797,29 @@ async def send(self, envelope: Envelope) -> None:
await self._restart_node()
await self._node_client.send_envelope(envelope)
+ async def _send_loop(self) -> None:
+ """Handle message in the send queue."""
+
+ if not self._send_queue or not self._node_client: # pragma: nocover
+ self.logger.error("Send loop not started cause not connected properly.")
+ return
+
+ while self.is_connected:
+ envelope = await self._send_queue.get()
+ await self._send_envelope_with_node_client(envelope)
+
+ async def send(self, envelope: Envelope) -> None:
+ """
+ Send messages.
+
+ :return: None
+ """
+ if not self._node_client or not self._send_queue:
+ raise ValueError("Node is not connected!") # pragma: nocover
+
+ self._ensure_valid_envelope_for_external_comms(envelope)
+ await self._send_queue.put(envelope)
+
async def _read_envelope_from_node(self) -> Optional[Envelope]:
if not self._node_client:
raise ValueError("Node is not connected!") # pragma: nocover
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index aae241665d..2c70c779fc 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -11,7 +11,7 @@ fingerprint:
README.md: QmWcd2zHiRZLgXCSGw9gZ35WfcKsMeNSQouqNAaZnPBDDR
__init__.py: QmYQuLNyQ8WTjgRYAoKAzoJEb7ocKXvM2hTyK4hsGch5D6
check_dependencies.py: QmP14nkQ8senwzdPdrZJLsA6EQ7zaKKEaLGDELhT42gp1P
- connection.py: QmXmCBy8AizGefC8JJo2nJZySY2kmevNgxxgMkJPvoNQRR
+ connection.py: QmXpvN8paXXrgx1oAvV1XEHGvxkgENGEpAQ4nCYKLzUq6d
libp2p_node/README.md: Qmak56XnWfarVxasiaGqYQWJaNVnEAh2hsLWstuFVND98w
libp2p_node/aea/api.go: QmdFR5Rmkk2FGVDwzgHtjobjAKyLejqk2CAYBCvcF23AG7
libp2p_node/aea/envelope.pb.go: QmRfUNGpCeVJfsW3H1MzCN4pwDWgumfyWufVFp6xvUjjug
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 84274a556f..ea7a1cd5a2 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmQ1FBNQezRPufMZDyVcW4KuADyKPQHb2Xo4qtLFcTgmAD
+fetchai/connections/p2p_libp2p,QmbL1bWiqvaTuHeQYLijBvgg4csksvtSEFCcF4s9r74SUo
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
diff --git a/tests/test_packages/test_connections/test_p2p_libp2p/test_errors.py b/tests/test_packages/test_connections/test_p2p_libp2p/test_errors.py
index f6c639015d..a90a17464b 100644
--- a/tests/test_packages/test_connections/test_p2p_libp2p/test_errors.py
+++ b/tests/test_packages/test_connections/test_p2p_libp2p/test_errors.py
@@ -259,7 +259,7 @@ async def test_reconnect_on_write_failed():
), pytest.raises(
Exception, match="expected"
):
- await con.send(Mock())
+ await con._send_envelope_with_node_client(Mock())
assert node.pipe.write.call_count == 2
restart_mock.assert_called_once()
From 074d13087243f0c449bd27fa0195aeb04f498c41 Mon Sep 17 00:00:00 2001
From: ali
Date: Mon, 10 May 2021 11:09:55 +0100
Subject: [PATCH 020/147] aligning locations across aw5 agents
---
packages/fetchai/agents/simple_seller_aw5/aea-config.yaml | 4 ++--
packages/hashes.csv | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/packages/fetchai/agents/simple_seller_aw5/aea-config.yaml b/packages/fetchai/agents/simple_seller_aw5/aea-config.yaml
index 3ea31b20ed..533d8b0fa9 100644
--- a/packages/fetchai/agents/simple_seller_aw5/aea-config.yaml
+++ b/packages/fetchai/agents/simple_seller_aw5/aea-config.yaml
@@ -99,8 +99,8 @@ models:
strategy:
args:
search_location:
- latitude: 51.5194
- longitude: 0.127
+ latitude: 51.5074
+ longitude: -0.1278
search_query:
constraint_type: ==
search_key: registration_service
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 84274a556f..9183bf3d06 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -24,7 +24,7 @@ fetchai/agents/simple_aggregator,QmaBUEUoLtvh77LBjUNoDgZWdGFpJ84hovN4JEkbwT4Dg3
fetchai/agents/simple_buyer_aw2,QmeFEVetkqfiX5FHRPzYWA5MsT6Nr1hFpWSyqDijXf5PXp
fetchai/agents/simple_buyer_aw5,QmP1GuNr3Vgyd95USSCB69hJszVgQn5DZPQwhPMY7Yp6H3
fetchai/agents/simple_seller_aw2,QmfFvf3BJkXLBC4BHA24n1qAc1yhZqvCHGK1mJJouhfxSL
-fetchai/agents/simple_seller_aw5,QmbhmmfAQTachJs6sXceqc3xBiTgkqZGTRuP1vPcrMaUk4
+fetchai/agents/simple_seller_aw5,QmbsvZ3TGrwAP7hP5NdH3ekfnCRN4Lcobrzan73DBHKh7t
fetchai/agents/simple_service_registration,QmdvXaondRwmtPG4jxnMkoufAUfePHg2fT4fKG7QnN7NKW
fetchai/agents/simple_service_search,QmVWLNNnhNdStWhSREzQaMBpU5HxpmhLTR89WdXMXTpRMf
fetchai/agents/tac_controller,QmeWpJcgY7C8k7woeJAr4QJqvW7X8U7AERReteYq1FhKNn
From 56e8b45d2db18a598cfe5073cddb5147dd0ea2db Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Mon, 10 May 2021 11:55:17 +0100
Subject: [PATCH 021/147] feat: connection check retry in soef
---
examples/tac_deploy/README.md | 2 ++
.../fetchai/connections/soef/connection.py | 28 ++++++++++++++++---
.../fetchai/connections/soef/connection.yaml | 5 ++--
packages/hashes.csv | 2 +-
tests/common/docker_image.py | 2 +-
5 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/examples/tac_deploy/README.md b/examples/tac_deploy/README.md
index e0e6083689..7cc979ae95 100644
--- a/examples/tac_deploy/README.md
+++ b/examples/tac_deploy/README.md
@@ -95,8 +95,10 @@ grep -rl 'TAKE CARE! Circumventing controller identity check!' output_dir/ | sor
grep -rl 'TAKE CARE! Circumventing controller identity check!' output_dir/ | wc -l
grep -rnw 'SOEF Network Connection Error' output_dir/ | wc -l
grep -rnw 'SOEF Server Bad Response Error' output_dir/ | wc -l
+gret -rnw ' Connection reset by peer' output_dir/ | wc -l
grep -rnw 'Failure during pipe closing.' output_dir/ | wc -l
grep -rnw "Couldn't connect to libp2p process within timeout" output_dir/ | wc -l
+grep -rnw 'Exception on connect:' output_dir/ | wc -l
grep -rnw 'Exception' output_dir/ | wc -l
grep -rnw 'connect to libp2p process within timeout' output_dir/ | wc -l
grep -rnw 'handling valid transaction' output_dir/tac_controller/ | wc -l
diff --git a/packages/fetchai/connections/soef/connection.py b/packages/fetchai/connections/soef/connection.py
index c50cdaac6f..bc15e195eb 100644
--- a/packages/fetchai/connections/soef/connection.py
+++ b/packages/fetchai/connections/soef/connection.py
@@ -220,7 +220,8 @@ def __init__(
chain_identifier: Optional[str] = None,
token_storage_path: Optional[str] = None,
logger: logging.Logger = _default_logger,
- connection_check_timeout: float = 15,
+ connection_check_timeout: float = 15.0,
+ connection_check_max_retries: int = 3,
):
"""
Initialize.
@@ -246,6 +247,7 @@ def __init__(
self.base_url = "https://{}:{}".format(soef_addr, soef_port)
self.oef_search_dialogues = OefSearchDialogues()
self.connection_check_timeout = connection_check_timeout
+ self.connection_check_max_retries = connection_check_max_retries
self._token_storage_path = token_storage_path
if self._token_storage_path is not None:
@@ -1071,14 +1073,23 @@ async def _check_server_reachable(self) -> None:
)
except asyncio.TimeoutError:
raise SOEFNetworkConnectionError(
- f"Server can not be reached within timeout = {self.connection_check_timeout}!"
+ f"Server can not be reached within timeout={self.connection_check_timeout}!"
)
async def connect(self) -> None:
"""Connect channel set queues and executor pool."""
self._loop = asyncio.get_event_loop()
- await self._check_server_reachable()
+ reachable_check_count = 0
+ while reachable_check_count < self.connection_check_max_retries:
+ reachable_check_count += 1
+ try:
+ await self._check_server_reachable()
+ reachable_check_count = self.connection_check_max_retries
+ except Exception as e: # pragma: nocover
+ if reachable_check_count < self.connection_check_max_retries:
+ raise e
+ self.logger.debug(f"Exception during SOEF reachability check: {e}.")
self.in_queue = asyncio.Queue()
self._find_around_me_queue = asyncio.Queue()
@@ -1249,7 +1260,8 @@ class SOEFConnection(Connection):
"""The SOEFConnection connects the Simple OEF to the mailbox."""
connection_id = PUBLIC_ID
- DEFAULT_CONNECTION_CHECK_TIMEOUT: float = 15
+ DEFAULT_CONNECTION_CHECK_TIMEOUT: float = 15.0
+ DEFAULT_CONNECTION_CHECK_MAX_RETRIES: int = 3
def __init__(self, **kwargs: Any) -> None:
"""Initialize."""
@@ -1267,6 +1279,13 @@ def __init__(self, **kwargs: Any) -> None:
"connection_check_timeout", self.DEFAULT_CONNECTION_CHECK_TIMEOUT
),
)
+ connection_check_max_retries = cast(
+ int,
+ self.configuration.config.get(
+ "connection_check_max_retries",
+ self.DEFAULT_CONNECTION_CHECK_MAX_RETRIES,
+ ),
+ )
soef_addr = cast(str, self.configuration.config.get("soef_addr"))
soef_port = cast(int, self.configuration.config.get("soef_port"))
chain_identifier = cast(str, self.configuration.config.get("chain_identifier"))
@@ -1288,6 +1307,7 @@ def __init__(self, **kwargs: Any) -> None:
chain_identifier=chain_identifier,
token_storage_path=token_storage_path,
connection_check_timeout=connection_check_timeout,
+ connection_check_max_retries=connection_check_max_retries,
)
async def connect(self) -> None:
diff --git a/packages/fetchai/connections/soef/connection.yaml b/packages/fetchai/connections/soef/connection.yaml
index abfd94dc59..63ff14aa1d 100644
--- a/packages/fetchai/connections/soef/connection.yaml
+++ b/packages/fetchai/connections/soef/connection.yaml
@@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0'
fingerprint:
README.md: QmZk6CdnvtRHMRCiq9JjUsQ3jhyJyeGdnfn7VpgHvQEccK
__init__.py: Qmd5VBGFJHXFe1H45XoUh5mMSYBwvLSViJuGFeMgbPdQts
- connection.py: QmYn2wUxiTxT3hGoJeKvCUyP6NMYWeAzot7FdCkPBx6ydD
+ connection.py: QmcK1AAnJvgp8Md6wHjUBkfQyGqhzFeWtF4j9gCRfS4V2E
fingerprint_ignore_patterns: []
connections: []
protocols:
@@ -17,7 +17,8 @@ class_name: SOEFConnection
config:
api_key: TwiCIriSl0mLahw17pyqoA
chain_identifier: fetchai_v2_testnet_stable
- connection_check_timeout: 15
+ connection_check_max_retries: 3
+ connection_check_timeout: 15.0
soef_addr: s-oef.fetch.ai
soef_port: 443
token_storage_path: soef_token.txt
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 84274a556f..905f26774b 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -46,7 +46,7 @@ fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
fetchai/connections/scaffold,QmSrZ99ccW1VDxo6kR8TWENzNXcFWmV7aje6RNcSEwqRyd
-fetchai/connections/soef,QmNSjceuUjK5DZkySRt2D789ty6MDSAGDkTvbirBEk2k7f
+fetchai/connections/soef,QmcH951byBDs5fbjRF7CkLuUYitcRNHf9vuc8DP3hAceMF
fetchai/connections/stub,QmQjSUgExNU6Wgks9rwBa1zYsjdPkzs7FZy3SS2Lo3bcqz
fetchai/connections/tcp,QmceuewTDJ8eKeCkcHH1enwF7EEocajkmuHi7QptJB7r5j
fetchai/connections/webhook,QmQn8vSouUJrjzH7SNj148jRRDK3snRDMHMkB5GDHWBbMP
diff --git a/tests/common/docker_image.py b/tests/common/docker_image.py
index 7e08bb5bd6..2c35b780de 100644
--- a/tests/common/docker_image.py
+++ b/tests/common/docker_image.py
@@ -79,7 +79,7 @@ def _check_docker_binary_available(self):
result.stdout.decode("utf-8"),
)
if match is None:
- pytest.skip(f"cannot read version from the output of 'docker --version'")
+ pytest.skip("cannot read version from the output of 'docker --version'")
version = (int(match.group(1)), int(match.group(2)), int(match.group(3)))
if version < self.MINIMUM_DOCKER_VERSION:
pytest.skip(
From 37ae4a8560c136a82e83d39d6d89dc9d314ddbc1 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Mon, 10 May 2021 12:02:15 +0100
Subject: [PATCH 022/147] fix: minor bug fix on new soef feat
---
packages/fetchai/connections/soef/connection.py | 2 +-
packages/fetchai/connections/soef/connection.yaml | 2 +-
packages/hashes.csv | 2 +-
tests/test_packages/test_connections/test_soef/test_soef.py | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/packages/fetchai/connections/soef/connection.py b/packages/fetchai/connections/soef/connection.py
index bc15e195eb..e5ae90a33e 100644
--- a/packages/fetchai/connections/soef/connection.py
+++ b/packages/fetchai/connections/soef/connection.py
@@ -1087,7 +1087,7 @@ async def connect(self) -> None:
await self._check_server_reachable()
reachable_check_count = self.connection_check_max_retries
except Exception as e: # pragma: nocover
- if reachable_check_count < self.connection_check_max_retries:
+ if reachable_check_count == self.connection_check_max_retries:
raise e
self.logger.debug(f"Exception during SOEF reachability check: {e}.")
diff --git a/packages/fetchai/connections/soef/connection.yaml b/packages/fetchai/connections/soef/connection.yaml
index 63ff14aa1d..a5890f9041 100644
--- a/packages/fetchai/connections/soef/connection.yaml
+++ b/packages/fetchai/connections/soef/connection.yaml
@@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0'
fingerprint:
README.md: QmZk6CdnvtRHMRCiq9JjUsQ3jhyJyeGdnfn7VpgHvQEccK
__init__.py: Qmd5VBGFJHXFe1H45XoUh5mMSYBwvLSViJuGFeMgbPdQts
- connection.py: QmcK1AAnJvgp8Md6wHjUBkfQyGqhzFeWtF4j9gCRfS4V2E
+ connection.py: Qmaim6gumUXNsgQazNz2gjdSMh11b9pe9DcAYb6T919vpp
fingerprint_ignore_patterns: []
connections: []
protocols:
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 905f26774b..90f5befa43 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -46,7 +46,7 @@ fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
fetchai/connections/scaffold,QmSrZ99ccW1VDxo6kR8TWENzNXcFWmV7aje6RNcSEwqRyd
-fetchai/connections/soef,QmcH951byBDs5fbjRF7CkLuUYitcRNHf9vuc8DP3hAceMF
+fetchai/connections/soef,Qmd1mp7XZZAQp88wie486WYDYJyYFpZ5MHrSusU6MDpLzq
fetchai/connections/stub,QmQjSUgExNU6Wgks9rwBa1zYsjdPkzs7FZy3SS2Lo3bcqz
fetchai/connections/tcp,QmceuewTDJ8eKeCkcHH1enwF7EEocajkmuHi7QptJB7r5j
fetchai/connections/webhook,QmQn8vSouUJrjzH7SNj148jRRDK3snRDMHMkB5GDHWBbMP
diff --git a/tests/test_packages/test_connections/test_soef/test_soef.py b/tests/test_packages/test_connections/test_soef/test_soef.py
index 651200de8a..bbdbbcd5a5 100644
--- a/tests/test_packages/test_connections/test_soef/test_soef.py
+++ b/tests/test_packages/test_connections/test_soef/test_soef.py
@@ -620,7 +620,7 @@ async def slow_request(*args, **kwargs):
), patch.object(self.connection.channel, "connection_check_timeout", 0.01):
with pytest.raises(
SOEFNetworkConnectionError,
- match="
Date: Mon, 10 May 2021 13:25:21 +0100
Subject: [PATCH 024/147] fix: pylint error
---
packages/fetchai/connections/soef/connection.py | 2 +-
packages/fetchai/connections/soef/connection.yaml | 2 +-
packages/hashes.csv | 2 +-
plugins/aea-ledger-ethereum/tests/docker_image.py | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/packages/fetchai/connections/soef/connection.py b/packages/fetchai/connections/soef/connection.py
index e5ae90a33e..82583a0007 100644
--- a/packages/fetchai/connections/soef/connection.py
+++ b/packages/fetchai/connections/soef/connection.py
@@ -1086,7 +1086,7 @@ async def connect(self) -> None:
try:
await self._check_server_reachable()
reachable_check_count = self.connection_check_max_retries
- except Exception as e: # pragma: nocover
+ except Exception as e: # pylint: disable=broad-except # pragma: nocover
if reachable_check_count == self.connection_check_max_retries:
raise e
self.logger.debug(f"Exception during SOEF reachability check: {e}.")
diff --git a/packages/fetchai/connections/soef/connection.yaml b/packages/fetchai/connections/soef/connection.yaml
index a5890f9041..4e6b33863e 100644
--- a/packages/fetchai/connections/soef/connection.yaml
+++ b/packages/fetchai/connections/soef/connection.yaml
@@ -8,7 +8,7 @@ aea_version: '>=1.0.0, <2.0.0'
fingerprint:
README.md: QmZk6CdnvtRHMRCiq9JjUsQ3jhyJyeGdnfn7VpgHvQEccK
__init__.py: Qmd5VBGFJHXFe1H45XoUh5mMSYBwvLSViJuGFeMgbPdQts
- connection.py: Qmaim6gumUXNsgQazNz2gjdSMh11b9pe9DcAYb6T919vpp
+ connection.py: QmQCvwPhyGZYwsUCekjuHvpBPpkjGmNGGPyphqbqwBaZwy
fingerprint_ignore_patterns: []
connections: []
protocols:
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 90f5befa43..10a73bf620 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -46,7 +46,7 @@ fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
fetchai/connections/scaffold,QmSrZ99ccW1VDxo6kR8TWENzNXcFWmV7aje6RNcSEwqRyd
-fetchai/connections/soef,Qmd1mp7XZZAQp88wie486WYDYJyYFpZ5MHrSusU6MDpLzq
+fetchai/connections/soef,QmXYKva5pyxunoDuw8EbMcRLLbZsLDvA22chGq4KMvoyys
fetchai/connections/stub,QmQjSUgExNU6Wgks9rwBa1zYsjdPkzs7FZy3SS2Lo3bcqz
fetchai/connections/tcp,QmceuewTDJ8eKeCkcHH1enwF7EEocajkmuHi7QptJB7r5j
fetchai/connections/webhook,QmQn8vSouUJrjzH7SNj148jRRDK3snRDMHMkB5GDHWBbMP
diff --git a/plugins/aea-ledger-ethereum/tests/docker_image.py b/plugins/aea-ledger-ethereum/tests/docker_image.py
index ce8f63538d..10b36ed7d1 100644
--- a/plugins/aea-ledger-ethereum/tests/docker_image.py
+++ b/plugins/aea-ledger-ethereum/tests/docker_image.py
@@ -65,7 +65,7 @@ def _check_docker_binary_available(self):
["docker", "--version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
if result.returncode != 0:
- pytest.skip(f"'docker --version' failed with exit code {result.returncode}")
+ pytest.skip("'docker --version' failed with exit code {result.returncode}")
match = re.search(
r"Docker version ([0-9]+)\.([0-9]+)\.([0-9]+)",
From 0e8a6b6cb9722e01d8e1fa783045da7eb55bf3ec Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 10 May 2021 14:46:22 +0200
Subject: [PATCH 025/147] fix: minor refactoring to add bump of plugins
---
scripts/bump_aea_version.py | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index c5154138ca..ccf3f9df98 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -165,23 +165,30 @@ def parse_args() -> argparse.Namespace:
return arguments_
-if __name__ == "__main__":
- arguments = parse_args()
- _new_version_str = arguments.new_version
+def update_aea_version(new_version_string: str) -> bool:
+ """
+ Update aea version.
+ :param new_version_string: the new version string.
+ :return: True if the update actually happened; False otherwise.
+ """
# validate new version
- _new_version: Version = Version(_new_version_str)
- _new_version_str = str(_new_version)
- _current_version_str = update_version_for_aea(_new_version_str)
+ new_version: Version = Version(new_version_string)
+ new_version_string = str(new_version)
+ _current_version_str = update_version_for_aea(new_version_string)
# validate current version
_current_version: Version = Version(_current_version_str)
_current_version_str = str(_current_version)
- update_version_for_files(_current_version_str, _new_version_str)
+ update_version_for_files(_current_version_str, new_version_string)
- have_updated_specifier_set = update_aea_version_specifiers(
- _current_version, _new_version
- )
+ return update_aea_version_specifiers(_current_version, new_version)
+
+
+if __name__ == "__main__":
+ arguments = parse_args()
+ new_version_str = arguments.new_version
+ have_updated_specifier_set = update_aea_version(new_version_str)
print("OK")
return_code = 0
From 85b585e5ec753a7b6d4b2ff8d9c308cae937bc79 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 10 May 2021 16:04:13 +0300
Subject: [PATCH 026/147] libp2p connection pipe reconnect attempt
---
.../connections/p2p_libp2p/connection.py | 52 +++++++++++++++++--
.../connections/p2p_libp2p/connection.yaml | 2 +-
packages/hashes.csv | 2 +-
.../test_p2p_libp2p/test_communication.py | 2 +-
.../test_p2p_libp2p/test_errors.py | 32 ++++++++++++
5 files changed, 82 insertions(+), 8 deletions(-)
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.py b/packages/fetchai/connections/p2p_libp2p/connection.py
index af53df2914..1a108346e7 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.py
+++ b/packages/fetchai/connections/p2p_libp2p/connection.py
@@ -350,6 +350,14 @@ def _child_watcher_callback(self, *_) -> None: # type: ignore # pragma: nocover
f"Node process with pid {self.proc.pid} was terminated with returncode {returncode}"
)
+ def is_proccess_running(self) -> bool:
+ """Check process is running."""
+ if not self.proc:
+ return False
+
+ self.proc.poll()
+ return self.proc.returncode is None
+
async def start(self) -> None:
"""
Start the node.
@@ -786,16 +794,43 @@ async def _send_envelope_with_node_client(self, envelope: Envelope) -> None:
if not self._node_client: # pragma: nocover
raise ValueError(f"Node client not set! Can not send envelope: {envelope}")
+ if not self.node.pipe: # pragma: nocover
+ raise ValueError("Node is not connected")
+
try:
await self._node_client.send_envelope(envelope)
+ return
+ except asyncio.CancelledError: # pylint: disable=try-except-raise
+ raise # pragma: nocover
+ except Exception as e: # pylint: disable=broad-except
+ self.logger.exception(
+ f"Failed to send. Exception: {e}. Try recover connection to node and send again."
+ )
+
+ try:
+ if self.node.is_proccess_running():
+ await self.node.pipe.connect()
+ await self._node_client.send_envelope(envelope)
+ self.logger.info("Envelope sent after reconnect to node")
+ return
except asyncio.CancelledError: # pylint: disable=try-except-raise
raise # pragma: nocover
except Exception as e: # pylint: disable=broad-except
+ self.logger.info("Envelope sending failed after reconnect to node")
self.logger.exception(
- f"Failed to send. Exception: {e}. Try reconnect to node and read again."
+ f"Failed to send after pipe reconnect. Exception: {e}. Try recover connection to node and send again."
)
+
+ try:
await self._restart_node()
await self._node_client.send_envelope(envelope)
+ except asyncio.CancelledError: # pylint: disable=try-except-raise
+ raise # pragma: nocover
+ except Exception as e: # pylint: disable=broad-except
+ self.logger.exception(
+ f"Failed to send after node restart. Exception: {e}. Try recover connection to node and send again."
+ )
+ raise
async def _send_loop(self) -> None:
"""Handle message in the send queue."""
@@ -803,10 +838,17 @@ async def _send_loop(self) -> None:
if not self._send_queue or not self._node_client: # pragma: nocover
self.logger.error("Send loop not started cause not connected properly.")
return
-
- while self.is_connected:
- envelope = await self._send_queue.get()
- await self._send_envelope_with_node_client(envelope)
+ try:
+ while self.is_connected:
+ envelope = await self._send_queue.get()
+ await self._send_envelope_with_node_client(envelope)
+ except asyncio.CancelledError: # pylint: disable=try-except-raise
+ raise # pragma: nocover
+ except Exception: # pylint: disable=broad-except # pragma: nocover
+ self.logger.exception(
+ f"Failed to send an aenvelope {envelope}. Stop connection."
+ )
+ await self.disconnect()
async def send(self, envelope: Envelope) -> None:
"""
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index 2c70c779fc..8366369869 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -11,7 +11,7 @@ fingerprint:
README.md: QmWcd2zHiRZLgXCSGw9gZ35WfcKsMeNSQouqNAaZnPBDDR
__init__.py: QmYQuLNyQ8WTjgRYAoKAzoJEb7ocKXvM2hTyK4hsGch5D6
check_dependencies.py: QmP14nkQ8senwzdPdrZJLsA6EQ7zaKKEaLGDELhT42gp1P
- connection.py: QmXpvN8paXXrgx1oAvV1XEHGvxkgENGEpAQ4nCYKLzUq6d
+ connection.py: QmSw9z9NhFDCrC8UFFCyZox8Tzx3XrWeEnGJxABEvm3KVL
libp2p_node/README.md: Qmak56XnWfarVxasiaGqYQWJaNVnEAh2hsLWstuFVND98w
libp2p_node/aea/api.go: QmdFR5Rmkk2FGVDwzgHtjobjAKyLejqk2CAYBCvcF23AG7
libp2p_node/aea/envelope.pb.go: QmRfUNGpCeVJfsW3H1MzCN4pwDWgumfyWufVFp6xvUjjug
diff --git a/packages/hashes.csv b/packages/hashes.csv
index ea7a1cd5a2..58268b6fef 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmbL1bWiqvaTuHeQYLijBvgg4csksvtSEFCcF4s9r74SUo
+fetchai/connections/p2p_libp2p,QmPDkW1HCtHdg3ovyrat6DYh1Hme76SsDFwzX7hPDPYtUW
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
diff --git a/tests/test_packages/test_connections/test_p2p_libp2p/test_communication.py b/tests/test_packages/test_connections/test_p2p_libp2p/test_communication.py
index 593647bc4e..8bc1c0c342 100644
--- a/tests/test_packages/test_connections/test_p2p_libp2p/test_communication.py
+++ b/tests/test_packages/test_connections/test_p2p_libp2p/test_communication.py
@@ -790,7 +790,7 @@ def test_envelope_routed(self):
self.multiplexer2.put(envelope)
delivered_envelope = self.multiplexer1.get(block=True, timeout=20)
_mock_logger.assert_called_with(
- "Failed to send. Exception: some error. Try reconnect to node and read again."
+ "Failed to send after pipe reconnect. Exception: some error. Try recover connection to node and send again."
)
assert delivered_envelope is not None
diff --git a/tests/test_packages/test_connections/test_p2p_libp2p/test_errors.py b/tests/test_packages/test_connections/test_p2p_libp2p/test_errors.py
index a90a17464b..133eaf475f 100644
--- a/tests/test_packages/test_connections/test_p2p_libp2p/test_errors.py
+++ b/tests/test_packages/test_connections/test_p2p_libp2p/test_errors.py
@@ -265,6 +265,38 @@ async def test_reconnect_on_write_failed():
restart_mock.assert_called_once()
+@pytest.mark.asyncio
+async def test_reconnect_on_write_failed_reconnect_pipe():
+ """Test node restart on write fail."""
+ host = "localhost"
+ port = "10000"
+ with patch(
+ "packages.fetchai.connections.p2p_libp2p.connection.P2PLibp2pConnection._check_node_built",
+ return_value="./",
+ ), patch("tests.conftest.build_node"), tempfile.TemporaryDirectory() as data_dir:
+ con = _make_libp2p_connection(
+ port=port, host=host, data_dir=data_dir, build_directory=data_dir
+ )
+
+ node = Libp2pNode(Mock(), Mock(), "tmp", "tmp")
+ f = Future()
+ f.set_result(None)
+ con.node = node
+ node.pipe = Mock()
+ node.pipe.connect = Mock(return_value=f)
+ node.pipe.write = Mock(side_effect=[Exception("expected"), f])
+
+ con._node_client = node.get_client()
+
+ with patch.object(con, "_ensure_valid_envelope_for_external_comms"), patch.object(
+ node, "is_proccess_running", return_value=True
+ ):
+ await con._send_envelope_with_node_client(Mock())
+
+ assert node.pipe.write.call_count == 2
+ assert node.pipe.connect.call_count == 1
+
+
@pytest.mark.asyncio
async def test_reconnect_on_read_failed():
"""Test node restart on read fail."""
From bbb0e7c08750f7046a283f7589a7a2e3b911b693 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 10 May 2021 16:18:00 +0300
Subject: [PATCH 027/147] log level adjust
---
packages/fetchai/connections/p2p_libp2p/connection.py | 3 +--
packages/fetchai/connections/p2p_libp2p/connection.yaml | 2 +-
packages/hashes.csv | 2 +-
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.py b/packages/fetchai/connections/p2p_libp2p/connection.py
index 1a108346e7..7cf3e63a14 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.py
+++ b/packages/fetchai/connections/p2p_libp2p/connection.py
@@ -811,12 +811,11 @@ async def _send_envelope_with_node_client(self, envelope: Envelope) -> None:
if self.node.is_proccess_running():
await self.node.pipe.connect()
await self._node_client.send_envelope(envelope)
- self.logger.info("Envelope sent after reconnect to node")
+ self.logger.debug("Envelope sent after reconnect to node")
return
except asyncio.CancelledError: # pylint: disable=try-except-raise
raise # pragma: nocover
except Exception as e: # pylint: disable=broad-except
- self.logger.info("Envelope sending failed after reconnect to node")
self.logger.exception(
f"Failed to send after pipe reconnect. Exception: {e}. Try recover connection to node and send again."
)
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index 8366369869..385a5621c8 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -11,7 +11,7 @@ fingerprint:
README.md: QmWcd2zHiRZLgXCSGw9gZ35WfcKsMeNSQouqNAaZnPBDDR
__init__.py: QmYQuLNyQ8WTjgRYAoKAzoJEb7ocKXvM2hTyK4hsGch5D6
check_dependencies.py: QmP14nkQ8senwzdPdrZJLsA6EQ7zaKKEaLGDELhT42gp1P
- connection.py: QmSw9z9NhFDCrC8UFFCyZox8Tzx3XrWeEnGJxABEvm3KVL
+ connection.py: Qmc5xhrj2GYijSyzMFH1SE3x4p5zqRjwfgkcYieVU9irdX
libp2p_node/README.md: Qmak56XnWfarVxasiaGqYQWJaNVnEAh2hsLWstuFVND98w
libp2p_node/aea/api.go: QmdFR5Rmkk2FGVDwzgHtjobjAKyLejqk2CAYBCvcF23AG7
libp2p_node/aea/envelope.pb.go: QmRfUNGpCeVJfsW3H1MzCN4pwDWgumfyWufVFp6xvUjjug
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 58268b6fef..09bdee7849 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmPDkW1HCtHdg3ovyrat6DYh1Hme76SsDFwzX7hPDPYtUW
+fetchai/connections/p2p_libp2p,QmWZBVf4FYUFwhbMyEtTWYto7ZB38rvP9oPmH5Ypomy7CQ
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
From 3bde071e10761b8a1eefd56c1cdeaddb25f967c5 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 10 May 2021 16:12:02 +0200
Subject: [PATCH 028/147] refactor 'bump_aea_version' script
Use functor pattern; this will allow less code duplication
for the incoming feature (#2504)
---
scripts/bump_aea_version.py | 206 +++++++++++++++++++++++-------------
1 file changed, 130 insertions(+), 76 deletions(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index ccf3f9df98..9f2a1d0cdd 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -21,9 +21,13 @@
"""Bump the AEA version throughout the code base."""
import argparse
+import inspect
+import os
import re
import sys
+from functools import wraps
from pathlib import Path
+from typing import Optional
from packaging.version import Version
@@ -44,6 +48,8 @@
PACKAGES_DIR = Path("packages")
TESTS_DIR = Path("tests")
AEA_DIR = Path("aea")
+CUR_PATH = os.path.dirname(inspect.getfile(inspect.currentframe())) # type: ignore
+ROOT_DIR = os.path.join(CUR_PATH, "..")
CONFIGURATION_FILENAME_REGEX = re.compile(
"|".join(
[
@@ -59,62 +65,126 @@
IGNORE_DIRS = [Path(".git")]
-def update_version_for_files(current_version: str, new_version: str) -> None:
- """
- Update the version.
+def check_executed(func):
+ """Check a functor has been already executed; if yes, raise error."""
- :param current_version: the current version
- :param new_version: the new version
- """
- files = [
- Path("benchmark", "run_from_branch.sh"),
- Path("deploy-image", "Dockerfile"),
- Path("develop-image", "docker-env.sh"),
- Path("docs", "quickstart.md"),
- Path("examples", "tac_deploy", "Dockerfile"),
- Path("scripts", "install.ps1"),
- Path("scripts", "install.sh"),
- Path("tests", "test_docs", "test_bash_yaml", "md_files", "bash-quickstart.md"),
- Path("user-image", "docker-env.sh"),
- ]
- for filepath in files:
- update_version_for_file(filepath, current_version, new_version)
-
-
-def update_version_for_aea(new_version: str) -> str:
- """
- Update version for file.
+ @wraps(func)
+ def wrapper(self, *args, **kwargs):
+ if self.is_executed:
+ raise ValueError("already executed")
+ self._executed = True
+ self._result = func(self, *args, **kwargs)
- :param new_version: the new version
- :return: the current version
- """
- current_version = ""
- path = Path("aea", "__version__.py")
- with open(path, "rt") as fin:
- for line in fin:
- if "__version__" not in line:
- continue
- match = re.search('__version__ = "(.*)"', line)
- if match is None:
- raise ValueError("Current version is not well formatted.")
- current_version = match.group(1)
- if current_version == "":
- raise ValueError("No version found!")
- update_version_for_file(path, current_version, new_version)
- return current_version
-
-
-def update_version_for_file(path: Path, current_version: str, new_version: str) -> None:
- """
- Update version for file.
+ return wrapper
- :param path: the file path
- :param current_version: the current version
- :param new_version: the new version
- """
- content = path.read_text()
- content = content.replace(current_version, new_version)
- path.write_text(content)
+
+class PythonPackageVersionBumper:
+ """Utility class to bump Python package versions."""
+
+ def __init__(self, root_dir: Path, python_pkg_dir: Path, new_version: Version):
+ """
+ Initialize the utility class.
+
+ :param root_dir: the root directory from which to look for files.
+ :param python_pkg_dir: the path to the Python package to upgrade.
+ :param new_version: the new version.
+ """
+ self.root_dir = root_dir
+ self.python_pkg_dir = python_pkg_dir
+ self.new_version = new_version
+
+ self._current_version = None
+
+ # functor pattern
+ self._executed: bool = False
+ self._result: Optional[bool] = None
+
+ @property
+ def is_executed(self) -> bool:
+ """
+ Return true if the functor has been executed; false otherwise.
+
+ :return: True if it has been executed, False otherwise.
+ """
+ return self._executed
+
+ @property
+ def result(self) -> bool:
+ """Get the result."""
+ if not self.is_executed:
+ raise ValueError("not executed yet")
+ return self._result
+
+ @check_executed
+ def run(self) -> bool:
+ """Main entrypoint."""
+ new_version_string = str(self.new_version)
+ current_version_str = self.update_version_for_aea(new_version_string)
+
+ # validate current version
+ current_version: Version = Version(current_version_str)
+ current_version_str = str(current_version)
+ self._current_version = current_version_str
+ self.update_version_for_files()
+
+ return update_aea_version_specifiers(current_version, self.new_version)
+
+ def update_version_for_files(self) -> None:
+ """Update the version."""
+ files = [
+ Path("benchmark", "run_from_branch.sh"),
+ Path("deploy-image", "Dockerfile"),
+ Path("develop-image", "docker-env.sh"),
+ Path("docs", "quickstart.md"),
+ Path("examples", "tac_deploy", "Dockerfile"),
+ Path("scripts", "install.ps1"),
+ Path("scripts", "install.sh"),
+ Path(
+ "tests", "test_docs", "test_bash_yaml", "md_files", "bash-quickstart.md"
+ ),
+ Path("user-image", "docker-env.sh"),
+ ]
+ for filepath in files:
+ self.update_version_for_file(
+ filepath, self._current_version, str(self.new_version)
+ )
+
+ def update_version_for_aea(self, new_version: str) -> str:
+ """
+ Update version for file.
+
+ :param new_version: the new version
+ :return: the current version
+ """
+ current_version = ""
+ path = Path("aea", "__version__.py")
+ with open(path, "rt") as fin:
+ for line in fin:
+ if "__version__" not in line:
+ continue
+ match = re.search('__version__ = "(.*)"', line)
+ if match is None:
+ raise ValueError("Current version is not well formatted.")
+ current_version = match.group(1)
+ if current_version == "":
+ raise ValueError("No version found!")
+ self.update_version_for_file(path, current_version, new_version)
+ return current_version
+
+ @classmethod
+ def update_version_for_file(
+ cls, path: Path, current_version: str, new_version: str
+ ) -> None:
+ """
+ Update version for file.
+
+ :param path: the file path
+ :param current_version: the current version
+ :param new_version: the new version
+ """
+ content = path.read_text()
+ content = content.replace(current_version, new_version)
+ path.write_text(content)
def update_aea_version_specifiers(old_version: Version, new_version: Version) -> bool:
@@ -158,37 +228,21 @@ def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser("bump_aea_version")
parser.add_argument(
- "--new-version", type=str, required=True, help="The new version."
+ "--new-version", type=str, required=True, help="The new AEA version."
)
parser.add_argument("--no-fingerprint", action="store_true")
arguments_ = parser.parse_args()
return arguments_
-def update_aea_version(new_version_string: str) -> bool:
- """
- Update aea version.
-
- :param new_version_string: the new version string.
- :return: True if the update actually happened; False otherwise.
- """
- # validate new version
- new_version: Version = Version(new_version_string)
- new_version_string = str(new_version)
- _current_version_str = update_version_for_aea(new_version_string)
-
- # validate current version
- _current_version: Version = Version(_current_version_str)
- _current_version_str = str(_current_version)
- update_version_for_files(_current_version_str, new_version_string)
-
- return update_aea_version_specifiers(_current_version, new_version)
-
-
if __name__ == "__main__":
arguments = parse_args()
- new_version_str = arguments.new_version
- have_updated_specifier_set = update_aea_version(new_version_str)
+ new_aea_version = Version(arguments.new_version)
+
+ aea_version_bumper = PythonPackageVersionBumper(
+ AEA_DIR.parent, AEA_DIR, new_aea_version
+ )
+ have_updated_specifier_set = aea_version_bumper.run()
print("OK")
return_code = 0
From bbd5794c6092ab6036d298c1108870c02fdc4808 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Mon, 10 May 2021 17:12:40 +0300
Subject: [PATCH 029/147] libp2p utils tests
---
libs/go/libp2p_node/Makefile | 12 +
libs/go/libp2p_node/go.mod | 7 +-
libs/go/libp2p_node/go.sum | 7 +
libs/go/libp2p_node/mocks/mock_host.go | 224 +++++++++
libs/go/libp2p_node/mocks/mock_net.go | 150 ++++++
libs/go/libp2p_node/mocks/mock_network.go | 191 +++++++
libs/go/libp2p_node/mocks/mock_peerstore.go | 412 +++++++++++++++
libs/go/libp2p_node/utils/utils.go | 120 ++++-
libs/go/libp2p_node/utils/utils_test.go | 475 ++++++++++++++++++
.../connections/p2p_libp2p/connection.yaml | 12 +-
.../p2p_libp2p/libp2p_node/Makefile | 12 +
.../connections/p2p_libp2p/libp2p_node/go.mod | 7 +-
.../connections/p2p_libp2p/libp2p_node/go.sum | 7 +
.../p2p_libp2p/libp2p_node/mocks/mock_host.go | 224 +++++++++
.../p2p_libp2p/libp2p_node/mocks/mock_net.go | 150 ++++++
.../libp2p_node/mocks/mock_network.go | 191 +++++++
.../libp2p_node/mocks/mock_peerstore.go | 412 +++++++++++++++
.../p2p_libp2p/libp2p_node/utils/utils.go | 120 ++++-
.../libp2p_node/utils/utils_test.go | 475 ++++++++++++++++++
packages/hashes.csv | 2 +-
20 files changed, 3152 insertions(+), 58 deletions(-)
create mode 100644 libs/go/libp2p_node/Makefile
create mode 100644 libs/go/libp2p_node/mocks/mock_host.go
create mode 100644 libs/go/libp2p_node/mocks/mock_net.go
create mode 100644 libs/go/libp2p_node/mocks/mock_network.go
create mode 100644 libs/go/libp2p_node/mocks/mock_peerstore.go
create mode 100644 libs/go/libp2p_node/utils/utils_test.go
create mode 100644 packages/fetchai/connections/p2p_libp2p/libp2p_node/Makefile
create mode 100644 packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_host.go
create mode 100644 packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_net.go
create mode 100644 packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_network.go
create mode 100644 packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_peerstore.go
create mode 100644 packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils_test.go
diff --git a/libs/go/libp2p_node/Makefile b/libs/go/libp2p_node/Makefile
new file mode 100644
index 0000000000..ae14b117be
--- /dev/null
+++ b/libs/go/libp2p_node/Makefile
@@ -0,0 +1,12 @@
+test:
+ go test -gcflags=-l -p 1 -timeout 0 -count 1 -covermode=atomic -coverprofile=coverage.txt -v ./...
+ go tool cover -func=coverage.txt
+
+lint:
+ golines . -w
+ golangci-lint run
+
+build:
+ go build
+install:
+ go get -v -t -d ./...
\ No newline at end of file
diff --git a/libs/go/libp2p_node/go.mod b/libs/go/libp2p_node/go.mod
index a5d16c054d..18898cea10 100644
--- a/libs/go/libp2p_node/go.mod
+++ b/libs/go/libp2p_node/go.mod
@@ -3,11 +3,13 @@ module libp2p_node
go 1.13
require (
+ bou.ke/monkey v1.0.2
github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4 // indirect
github.com/btcsuite/btcd v0.20.1-beta
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/dave/dst v0.26.2 // indirect
github.com/ethereum/go-ethereum v1.9.25
+ github.com/golang/mock v1.5.0
github.com/golang/protobuf v1.4.2
github.com/ipfs/go-cid v0.0.5
github.com/joho/godotenv v1.3.0
@@ -16,18 +18,21 @@ require (
github.com/libp2p/go-libp2p-circuit v0.2.2
github.com/libp2p/go-libp2p-core v0.5.3
github.com/libp2p/go-libp2p-kad-dht v0.7.11
+ github.com/libp2p/go-libp2p-kbucket v0.4.1
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/multiformats/go-multiaddr v0.2.1
github.com/multiformats/go-multihash v0.0.13
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.7.1
- github.com/rs/zerolog v1.19.0
+ github.com/rs/zerolog v1.21.0
github.com/segmentio/golines v0.0.0-20200824192126-7f30d3046793 // indirect
github.com/sirupsen/logrus v1.7.0 // indirect
+ github.com/stretchr/testify v1.5.1
golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9
golang.org/x/mod v0.4.0 // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
google.golang.org/protobuf v1.25.0
honnef.co/go/tools v0.1.4 // indirect
+
)
diff --git a/libs/go/libp2p_node/go.sum b/libs/go/libp2p_node/go.sum
index cb99823bb5..f108665f5e 100644
--- a/libs/go/libp2p_node/go.sum
+++ b/libs/go/libp2p_node/go.sum
@@ -1,3 +1,5 @@
+bou.ke/monkey v1.0.2 h1:kWcnsrCNUatbxncxR/ThdYqbytgOIArtYWqcQLQzKLI=
+bou.ke/monkey v1.0.2/go.mod h1:OqickVX3tNx6t33n1xvtTtu85YN5s6cKwVug+oHMaIA=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
@@ -129,6 +131,8 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
+github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
@@ -566,6 +570,8 @@ github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubr
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.19.0 h1:hYz4ZVdUgjXTBUmrkrw55j1nHx68LfOKIQk5IYtyScg=
github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
+github.com/rs/zerolog v1.21.0 h1:Q3vdXlfLNT+OftyBHsU0Y445MD+8m8axjKgf2si0QcM=
+github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/segmentio/golines v0.0.0-20200824192126-7f30d3046793 h1:rhR7esJSmty+9ST6Gsp7mlQHkpISw2DiYjuFaz3dRDg=
@@ -837,6 +843,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/libs/go/libp2p_node/mocks/mock_host.go b/libs/go/libp2p_node/mocks/mock_host.go
new file mode 100644
index 0000000000..fb890fa843
--- /dev/null
+++ b/libs/go/libp2p_node/mocks/mock_host.go
@@ -0,0 +1,224 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: github.com/libp2p/go-libp2p-core/host (interfaces: Host)
+
+// Package mock_host is a generated GoMock package.
+package mocks
+
+import (
+ context "context"
+ reflect "reflect"
+
+ gomock "github.com/golang/mock/gomock"
+ connmgr "github.com/libp2p/go-libp2p-core/connmgr"
+ event "github.com/libp2p/go-libp2p-core/event"
+ network "github.com/libp2p/go-libp2p-core/network"
+ peer "github.com/libp2p/go-libp2p-core/peer"
+ peerstore "github.com/libp2p/go-libp2p-core/peerstore"
+ protocol "github.com/libp2p/go-libp2p-core/protocol"
+ multiaddr "github.com/multiformats/go-multiaddr"
+)
+
+// MockHost is a mock of Host interface.
+type MockHost struct {
+ ctrl *gomock.Controller
+ recorder *MockHostMockRecorder
+}
+
+// MockHostMockRecorder is the mock recorder for MockHost.
+type MockHostMockRecorder struct {
+ mock *MockHost
+}
+
+// NewMockHost creates a new mock instance.
+func NewMockHost(ctrl *gomock.Controller) *MockHost {
+ mock := &MockHost{ctrl: ctrl}
+ mock.recorder = &MockHostMockRecorder{mock}
+ return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockHost) EXPECT() *MockHostMockRecorder {
+ return m.recorder
+}
+
+// Addrs mocks base method.
+func (m *MockHost) Addrs() []multiaddr.Multiaddr {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Addrs")
+ ret0, _ := ret[0].([]multiaddr.Multiaddr)
+ return ret0
+}
+
+// Addrs indicates an expected call of Addrs.
+func (mr *MockHostMockRecorder) Addrs() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Addrs", reflect.TypeOf((*MockHost)(nil).Addrs))
+}
+
+// Close mocks base method.
+func (m *MockHost) Close() error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Close")
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Close indicates an expected call of Close.
+func (mr *MockHostMockRecorder) Close() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockHost)(nil).Close))
+}
+
+// ConnManager mocks base method.
+func (m *MockHost) ConnManager() connmgr.ConnManager {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "ConnManager")
+ ret0, _ := ret[0].(connmgr.ConnManager)
+ return ret0
+}
+
+// ConnManager indicates an expected call of ConnManager.
+func (mr *MockHostMockRecorder) ConnManager() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnManager", reflect.TypeOf((*MockHost)(nil).ConnManager))
+}
+
+// Connect mocks base method.
+func (m *MockHost) Connect(arg0 context.Context, arg1 peer.AddrInfo) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Connect", arg0, arg1)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Connect indicates an expected call of Connect.
+func (mr *MockHostMockRecorder) Connect(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockHost)(nil).Connect), arg0, arg1)
+}
+
+// EventBus mocks base method.
+func (m *MockHost) EventBus() event.Bus {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "EventBus")
+ ret0, _ := ret[0].(event.Bus)
+ return ret0
+}
+
+// EventBus indicates an expected call of EventBus.
+func (mr *MockHostMockRecorder) EventBus() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EventBus", reflect.TypeOf((*MockHost)(nil).EventBus))
+}
+
+// ID mocks base method.
+func (m *MockHost) ID() peer.ID {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "ID")
+ ret0, _ := ret[0].(peer.ID)
+ return ret0
+}
+
+// ID indicates an expected call of ID.
+func (mr *MockHostMockRecorder) ID() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockHost)(nil).ID))
+}
+
+// Mux mocks base method.
+func (m *MockHost) Mux() protocol.Switch {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Mux")
+ ret0, _ := ret[0].(protocol.Switch)
+ return ret0
+}
+
+// Mux indicates an expected call of Mux.
+func (mr *MockHostMockRecorder) Mux() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Mux", reflect.TypeOf((*MockHost)(nil).Mux))
+}
+
+// Network mocks base method.
+func (m *MockHost) Network() network.Network {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Network")
+ ret0, _ := ret[0].(network.Network)
+ return ret0
+}
+
+// Network indicates an expected call of Network.
+func (mr *MockHostMockRecorder) Network() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Network", reflect.TypeOf((*MockHost)(nil).Network))
+}
+
+// NewStream mocks base method.
+func (m *MockHost) NewStream(arg0 context.Context, arg1 peer.ID, arg2 ...protocol.ID) (network.Stream, error) {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{arg0, arg1}
+ for _, a := range arg2 {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "NewStream", varargs...)
+ ret0, _ := ret[0].(network.Stream)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// NewStream indicates an expected call of NewStream.
+func (mr *MockHostMockRecorder) NewStream(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{arg0, arg1}, arg2...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewStream", reflect.TypeOf((*MockHost)(nil).NewStream), varargs...)
+}
+
+// Peerstore mocks base method.
+func (m *MockHost) Peerstore() peerstore.Peerstore {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Peerstore")
+ ret0, _ := ret[0].(peerstore.Peerstore)
+ return ret0
+}
+
+// Peerstore indicates an expected call of Peerstore.
+func (mr *MockHostMockRecorder) Peerstore() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peerstore", reflect.TypeOf((*MockHost)(nil).Peerstore))
+}
+
+// RemoveStreamHandler mocks base method.
+func (m *MockHost) RemoveStreamHandler(arg0 protocol.ID) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "RemoveStreamHandler", arg0)
+}
+
+// RemoveStreamHandler indicates an expected call of RemoveStreamHandler.
+func (mr *MockHostMockRecorder) RemoveStreamHandler(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveStreamHandler", reflect.TypeOf((*MockHost)(nil).RemoveStreamHandler), arg0)
+}
+
+// SetStreamHandler mocks base method.
+func (m *MockHost) SetStreamHandler(arg0 protocol.ID, arg1 network.StreamHandler) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "SetStreamHandler", arg0, arg1)
+}
+
+// SetStreamHandler indicates an expected call of SetStreamHandler.
+func (mr *MockHostMockRecorder) SetStreamHandler(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetStreamHandler", reflect.TypeOf((*MockHost)(nil).SetStreamHandler), arg0, arg1)
+}
+
+// SetStreamHandlerMatch mocks base method.
+func (m *MockHost) SetStreamHandlerMatch(arg0 protocol.ID, arg1 func(string) bool, arg2 network.StreamHandler) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "SetStreamHandlerMatch", arg0, arg1, arg2)
+}
+
+// SetStreamHandlerMatch indicates an expected call of SetStreamHandlerMatch.
+func (mr *MockHostMockRecorder) SetStreamHandlerMatch(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetStreamHandlerMatch", reflect.TypeOf((*MockHost)(nil).SetStreamHandlerMatch), arg0, arg1, arg2)
+}
diff --git a/libs/go/libp2p_node/mocks/mock_net.go b/libs/go/libp2p_node/mocks/mock_net.go
new file mode 100644
index 0000000000..2f6b440075
--- /dev/null
+++ b/libs/go/libp2p_node/mocks/mock_net.go
@@ -0,0 +1,150 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: net (interfaces: Conn)
+
+// Package mock_net is a generated GoMock package.
+package mocks
+
+import (
+ net "net"
+ reflect "reflect"
+ time "time"
+
+ gomock "github.com/golang/mock/gomock"
+)
+
+// MockConn is a mock of Conn interface.
+type MockConn struct {
+ ctrl *gomock.Controller
+ recorder *MockConnMockRecorder
+}
+
+// MockConnMockRecorder is the mock recorder for MockConn.
+type MockConnMockRecorder struct {
+ mock *MockConn
+}
+
+// NewMockConn creates a new mock instance.
+func NewMockConn(ctrl *gomock.Controller) *MockConn {
+ mock := &MockConn{ctrl: ctrl}
+ mock.recorder = &MockConnMockRecorder{mock}
+ return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockConn) EXPECT() *MockConnMockRecorder {
+ return m.recorder
+}
+
+// Close mocks base method.
+func (m *MockConn) Close() error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Close")
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Close indicates an expected call of Close.
+func (mr *MockConnMockRecorder) Close() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockConn)(nil).Close))
+}
+
+// LocalAddr mocks base method.
+func (m *MockConn) LocalAddr() net.Addr {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "LocalAddr")
+ ret0, _ := ret[0].(net.Addr)
+ return ret0
+}
+
+// LocalAddr indicates an expected call of LocalAddr.
+func (mr *MockConnMockRecorder) LocalAddr() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockConn)(nil).LocalAddr))
+}
+
+// Read mocks base method.
+func (m *MockConn) Read(arg0 []byte) (int, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Read", arg0)
+ ret0, _ := ret[0].(int)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// Read indicates an expected call of Read.
+func (mr *MockConnMockRecorder) Read(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockConn)(nil).Read), arg0)
+}
+
+// RemoteAddr mocks base method.
+func (m *MockConn) RemoteAddr() net.Addr {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "RemoteAddr")
+ ret0, _ := ret[0].(net.Addr)
+ return ret0
+}
+
+// RemoteAddr indicates an expected call of RemoteAddr.
+func (mr *MockConnMockRecorder) RemoteAddr() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockConn)(nil).RemoteAddr))
+}
+
+// SetDeadline mocks base method.
+func (m *MockConn) SetDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetDeadline indicates an expected call of SetDeadline.
+func (mr *MockConnMockRecorder) SetDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockConn)(nil).SetDeadline), arg0)
+}
+
+// SetReadDeadline mocks base method.
+func (m *MockConn) SetReadDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetReadDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetReadDeadline indicates an expected call of SetReadDeadline.
+func (mr *MockConnMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockConn)(nil).SetReadDeadline), arg0)
+}
+
+// SetWriteDeadline mocks base method.
+func (m *MockConn) SetWriteDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetWriteDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetWriteDeadline indicates an expected call of SetWriteDeadline.
+func (mr *MockConnMockRecorder) SetWriteDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockConn)(nil).SetWriteDeadline), arg0)
+}
+
+// Write mocks base method.
+func (m *MockConn) Write(arg0 []byte) (int, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Write", arg0)
+ ret0, _ := ret[0].(int)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// Write indicates an expected call of Write.
+func (mr *MockConnMockRecorder) Write(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockConn)(nil).Write), arg0)
+}
diff --git a/libs/go/libp2p_node/mocks/mock_network.go b/libs/go/libp2p_node/mocks/mock_network.go
new file mode 100644
index 0000000000..ab38a029fc
--- /dev/null
+++ b/libs/go/libp2p_node/mocks/mock_network.go
@@ -0,0 +1,191 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: github.com/libp2p/go-libp2p-core/network (interfaces: Stream)
+
+// Package mock_network is a generated GoMock package.
+package mocks
+
+import (
+ reflect "reflect"
+ time "time"
+
+ gomock "github.com/golang/mock/gomock"
+ network "github.com/libp2p/go-libp2p-core/network"
+ protocol "github.com/libp2p/go-libp2p-core/protocol"
+)
+
+// MockStream is a mock of Stream interface.
+type MockStream struct {
+ ctrl *gomock.Controller
+ recorder *MockStreamMockRecorder
+}
+
+// MockStreamMockRecorder is the mock recorder for MockStream.
+type MockStreamMockRecorder struct {
+ mock *MockStream
+}
+
+// NewMockStream creates a new mock instance.
+func NewMockStream(ctrl *gomock.Controller) *MockStream {
+ mock := &MockStream{ctrl: ctrl}
+ mock.recorder = &MockStreamMockRecorder{mock}
+ return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockStream) EXPECT() *MockStreamMockRecorder {
+ return m.recorder
+}
+
+// Close mocks base method.
+func (m *MockStream) Close() error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Close")
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Close indicates an expected call of Close.
+func (mr *MockStreamMockRecorder) Close() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockStream)(nil).Close))
+}
+
+// Conn mocks base method.
+func (m *MockStream) Conn() network.Conn {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Conn")
+ ret0, _ := ret[0].(network.Conn)
+ return ret0
+}
+
+// Conn indicates an expected call of Conn.
+func (mr *MockStreamMockRecorder) Conn() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Conn", reflect.TypeOf((*MockStream)(nil).Conn))
+}
+
+// Protocol mocks base method.
+func (m *MockStream) Protocol() protocol.ID {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Protocol")
+ ret0, _ := ret[0].(protocol.ID)
+ return ret0
+}
+
+// Protocol indicates an expected call of Protocol.
+func (mr *MockStreamMockRecorder) Protocol() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Protocol", reflect.TypeOf((*MockStream)(nil).Protocol))
+}
+
+// Read mocks base method.
+func (m *MockStream) Read(arg0 []byte) (int, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Read", arg0)
+ ret0, _ := ret[0].(int)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// Read indicates an expected call of Read.
+func (mr *MockStreamMockRecorder) Read(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStream)(nil).Read), arg0)
+}
+
+// Reset mocks base method.
+func (m *MockStream) Reset() error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Reset")
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Reset indicates an expected call of Reset.
+func (mr *MockStreamMockRecorder) Reset() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reset", reflect.TypeOf((*MockStream)(nil).Reset))
+}
+
+// SetDeadline mocks base method.
+func (m *MockStream) SetDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetDeadline indicates an expected call of SetDeadline.
+func (mr *MockStreamMockRecorder) SetDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStream)(nil).SetDeadline), arg0)
+}
+
+// SetProtocol mocks base method.
+func (m *MockStream) SetProtocol(arg0 protocol.ID) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "SetProtocol", arg0)
+}
+
+// SetProtocol indicates an expected call of SetProtocol.
+func (mr *MockStreamMockRecorder) SetProtocol(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetProtocol", reflect.TypeOf((*MockStream)(nil).SetProtocol), arg0)
+}
+
+// SetReadDeadline mocks base method.
+func (m *MockStream) SetReadDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetReadDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetReadDeadline indicates an expected call of SetReadDeadline.
+func (mr *MockStreamMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStream)(nil).SetReadDeadline), arg0)
+}
+
+// SetWriteDeadline mocks base method.
+func (m *MockStream) SetWriteDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetWriteDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetWriteDeadline indicates an expected call of SetWriteDeadline.
+func (mr *MockStreamMockRecorder) SetWriteDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStream)(nil).SetWriteDeadline), arg0)
+}
+
+// Stat mocks base method.
+func (m *MockStream) Stat() network.Stat {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Stat")
+ ret0, _ := ret[0].(network.Stat)
+ return ret0
+}
+
+// Stat indicates an expected call of Stat.
+func (mr *MockStreamMockRecorder) Stat() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stat", reflect.TypeOf((*MockStream)(nil).Stat))
+}
+
+// Write mocks base method.
+func (m *MockStream) Write(arg0 []byte) (int, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Write", arg0)
+ ret0, _ := ret[0].(int)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// Write indicates an expected call of Write.
+func (mr *MockStreamMockRecorder) Write(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStream)(nil).Write), arg0)
+}
diff --git a/libs/go/libp2p_node/mocks/mock_peerstore.go b/libs/go/libp2p_node/mocks/mock_peerstore.go
new file mode 100644
index 0000000000..c1e2568dcc
--- /dev/null
+++ b/libs/go/libp2p_node/mocks/mock_peerstore.go
@@ -0,0 +1,412 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: github.com/libp2p/go-libp2p-core/peerstore (interfaces: Peerstore)
+
+// Package mock_peerstore is a generated GoMock package.
+package mocks
+
+import (
+ context "context"
+ reflect "reflect"
+ time "time"
+
+ gomock "github.com/golang/mock/gomock"
+ crypto "github.com/libp2p/go-libp2p-core/crypto"
+ peer "github.com/libp2p/go-libp2p-core/peer"
+ multiaddr "github.com/multiformats/go-multiaddr"
+)
+
+// MockPeerstore is a mock of Peerstore interface.
+type MockPeerstore struct {
+ ctrl *gomock.Controller
+ recorder *MockPeerstoreMockRecorder
+}
+
+// MockPeerstoreMockRecorder is the mock recorder for MockPeerstore.
+type MockPeerstoreMockRecorder struct {
+ mock *MockPeerstore
+}
+
+// NewMockPeerstore creates a new mock instance.
+func NewMockPeerstore(ctrl *gomock.Controller) *MockPeerstore {
+ mock := &MockPeerstore{ctrl: ctrl}
+ mock.recorder = &MockPeerstoreMockRecorder{mock}
+ return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockPeerstore) EXPECT() *MockPeerstoreMockRecorder {
+ return m.recorder
+}
+
+// AddAddr mocks base method.
+func (m *MockPeerstore) AddAddr(arg0 peer.ID, arg1 multiaddr.Multiaddr, arg2 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "AddAddr", arg0, arg1, arg2)
+}
+
+// AddAddr indicates an expected call of AddAddr.
+func (mr *MockPeerstoreMockRecorder) AddAddr(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAddr", reflect.TypeOf((*MockPeerstore)(nil).AddAddr), arg0, arg1, arg2)
+}
+
+// AddAddrs mocks base method.
+func (m *MockPeerstore) AddAddrs(arg0 peer.ID, arg1 []multiaddr.Multiaddr, arg2 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "AddAddrs", arg0, arg1, arg2)
+}
+
+// AddAddrs indicates an expected call of AddAddrs.
+func (mr *MockPeerstoreMockRecorder) AddAddrs(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAddrs", reflect.TypeOf((*MockPeerstore)(nil).AddAddrs), arg0, arg1, arg2)
+}
+
+// AddPrivKey mocks base method.
+func (m *MockPeerstore) AddPrivKey(arg0 peer.ID, arg1 crypto.PrivKey) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "AddPrivKey", arg0, arg1)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// AddPrivKey indicates an expected call of AddPrivKey.
+func (mr *MockPeerstoreMockRecorder) AddPrivKey(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPrivKey", reflect.TypeOf((*MockPeerstore)(nil).AddPrivKey), arg0, arg1)
+}
+
+// AddProtocols mocks base method.
+func (m *MockPeerstore) AddProtocols(arg0 peer.ID, arg1 ...string) error {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{arg0}
+ for _, a := range arg1 {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "AddProtocols", varargs...)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// AddProtocols indicates an expected call of AddProtocols.
+func (mr *MockPeerstoreMockRecorder) AddProtocols(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{arg0}, arg1...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProtocols", reflect.TypeOf((*MockPeerstore)(nil).AddProtocols), varargs...)
+}
+
+// AddPubKey mocks base method.
+func (m *MockPeerstore) AddPubKey(arg0 peer.ID, arg1 crypto.PubKey) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "AddPubKey", arg0, arg1)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// AddPubKey indicates an expected call of AddPubKey.
+func (mr *MockPeerstoreMockRecorder) AddPubKey(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPubKey", reflect.TypeOf((*MockPeerstore)(nil).AddPubKey), arg0, arg1)
+}
+
+// AddrStream mocks base method.
+func (m *MockPeerstore) AddrStream(arg0 context.Context, arg1 peer.ID) <-chan multiaddr.Multiaddr {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "AddrStream", arg0, arg1)
+ ret0, _ := ret[0].(<-chan multiaddr.Multiaddr)
+ return ret0
+}
+
+// AddrStream indicates an expected call of AddrStream.
+func (mr *MockPeerstoreMockRecorder) AddrStream(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddrStream", reflect.TypeOf((*MockPeerstore)(nil).AddrStream), arg0, arg1)
+}
+
+// Addrs mocks base method.
+func (m *MockPeerstore) Addrs(arg0 peer.ID) []multiaddr.Multiaddr {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Addrs", arg0)
+ ret0, _ := ret[0].([]multiaddr.Multiaddr)
+ return ret0
+}
+
+// Addrs indicates an expected call of Addrs.
+func (mr *MockPeerstoreMockRecorder) Addrs(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Addrs", reflect.TypeOf((*MockPeerstore)(nil).Addrs), arg0)
+}
+
+// ClearAddrs mocks base method.
+func (m *MockPeerstore) ClearAddrs(arg0 peer.ID) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "ClearAddrs", arg0)
+}
+
+// ClearAddrs indicates an expected call of ClearAddrs.
+func (mr *MockPeerstoreMockRecorder) ClearAddrs(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClearAddrs", reflect.TypeOf((*MockPeerstore)(nil).ClearAddrs), arg0)
+}
+
+// Close mocks base method.
+func (m *MockPeerstore) Close() error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Close")
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Close indicates an expected call of Close.
+func (mr *MockPeerstoreMockRecorder) Close() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPeerstore)(nil).Close))
+}
+
+// Get mocks base method.
+func (m *MockPeerstore) Get(arg0 peer.ID, arg1 string) (interface{}, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Get", arg0, arg1)
+ ret0, _ := ret[0].(interface{})
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// Get indicates an expected call of Get.
+func (mr *MockPeerstoreMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockPeerstore)(nil).Get), arg0, arg1)
+}
+
+// GetProtocols mocks base method.
+func (m *MockPeerstore) GetProtocols(arg0 peer.ID) ([]string, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetProtocols", arg0)
+ ret0, _ := ret[0].([]string)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetProtocols indicates an expected call of GetProtocols.
+func (mr *MockPeerstoreMockRecorder) GetProtocols(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProtocols", reflect.TypeOf((*MockPeerstore)(nil).GetProtocols), arg0)
+}
+
+// LatencyEWMA mocks base method.
+func (m *MockPeerstore) LatencyEWMA(arg0 peer.ID) time.Duration {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "LatencyEWMA", arg0)
+ ret0, _ := ret[0].(time.Duration)
+ return ret0
+}
+
+// LatencyEWMA indicates an expected call of LatencyEWMA.
+func (mr *MockPeerstoreMockRecorder) LatencyEWMA(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LatencyEWMA", reflect.TypeOf((*MockPeerstore)(nil).LatencyEWMA), arg0)
+}
+
+// PeerInfo mocks base method.
+func (m *MockPeerstore) PeerInfo(arg0 peer.ID) peer.AddrInfo {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "PeerInfo", arg0)
+ ret0, _ := ret[0].(peer.AddrInfo)
+ return ret0
+}
+
+// PeerInfo indicates an expected call of PeerInfo.
+func (mr *MockPeerstoreMockRecorder) PeerInfo(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerInfo", reflect.TypeOf((*MockPeerstore)(nil).PeerInfo), arg0)
+}
+
+// Peers mocks base method.
+func (m *MockPeerstore) Peers() peer.IDSlice {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Peers")
+ ret0, _ := ret[0].(peer.IDSlice)
+ return ret0
+}
+
+// Peers indicates an expected call of Peers.
+func (mr *MockPeerstoreMockRecorder) Peers() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peers", reflect.TypeOf((*MockPeerstore)(nil).Peers))
+}
+
+// PeersWithAddrs mocks base method.
+func (m *MockPeerstore) PeersWithAddrs() peer.IDSlice {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "PeersWithAddrs")
+ ret0, _ := ret[0].(peer.IDSlice)
+ return ret0
+}
+
+// PeersWithAddrs indicates an expected call of PeersWithAddrs.
+func (mr *MockPeerstoreMockRecorder) PeersWithAddrs() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeersWithAddrs", reflect.TypeOf((*MockPeerstore)(nil).PeersWithAddrs))
+}
+
+// PeersWithKeys mocks base method.
+func (m *MockPeerstore) PeersWithKeys() peer.IDSlice {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "PeersWithKeys")
+ ret0, _ := ret[0].(peer.IDSlice)
+ return ret0
+}
+
+// PeersWithKeys indicates an expected call of PeersWithKeys.
+func (mr *MockPeerstoreMockRecorder) PeersWithKeys() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeersWithKeys", reflect.TypeOf((*MockPeerstore)(nil).PeersWithKeys))
+}
+
+// PrivKey mocks base method.
+func (m *MockPeerstore) PrivKey(arg0 peer.ID) crypto.PrivKey {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "PrivKey", arg0)
+ ret0, _ := ret[0].(crypto.PrivKey)
+ return ret0
+}
+
+// PrivKey indicates an expected call of PrivKey.
+func (mr *MockPeerstoreMockRecorder) PrivKey(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrivKey", reflect.TypeOf((*MockPeerstore)(nil).PrivKey), arg0)
+}
+
+// PubKey mocks base method.
+func (m *MockPeerstore) PubKey(arg0 peer.ID) crypto.PubKey {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "PubKey", arg0)
+ ret0, _ := ret[0].(crypto.PubKey)
+ return ret0
+}
+
+// PubKey indicates an expected call of PubKey.
+func (mr *MockPeerstoreMockRecorder) PubKey(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PubKey", reflect.TypeOf((*MockPeerstore)(nil).PubKey), arg0)
+}
+
+// Put mocks base method.
+func (m *MockPeerstore) Put(arg0 peer.ID, arg1 string, arg2 interface{}) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Put", arg0, arg1, arg2)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Put indicates an expected call of Put.
+func (mr *MockPeerstoreMockRecorder) Put(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockPeerstore)(nil).Put), arg0, arg1, arg2)
+}
+
+// RecordLatency mocks base method.
+func (m *MockPeerstore) RecordLatency(arg0 peer.ID, arg1 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "RecordLatency", arg0, arg1)
+}
+
+// RecordLatency indicates an expected call of RecordLatency.
+func (mr *MockPeerstoreMockRecorder) RecordLatency(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordLatency", reflect.TypeOf((*MockPeerstore)(nil).RecordLatency), arg0, arg1)
+}
+
+// RemoveProtocols mocks base method.
+func (m *MockPeerstore) RemoveProtocols(arg0 peer.ID, arg1 ...string) error {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{arg0}
+ for _, a := range arg1 {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "RemoveProtocols", varargs...)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// RemoveProtocols indicates an expected call of RemoveProtocols.
+func (mr *MockPeerstoreMockRecorder) RemoveProtocols(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{arg0}, arg1...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProtocols", reflect.TypeOf((*MockPeerstore)(nil).RemoveProtocols), varargs...)
+}
+
+// SetAddr mocks base method.
+func (m *MockPeerstore) SetAddr(arg0 peer.ID, arg1 multiaddr.Multiaddr, arg2 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "SetAddr", arg0, arg1, arg2)
+}
+
+// SetAddr indicates an expected call of SetAddr.
+func (mr *MockPeerstoreMockRecorder) SetAddr(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddr", reflect.TypeOf((*MockPeerstore)(nil).SetAddr), arg0, arg1, arg2)
+}
+
+// SetAddrs mocks base method.
+func (m *MockPeerstore) SetAddrs(arg0 peer.ID, arg1 []multiaddr.Multiaddr, arg2 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "SetAddrs", arg0, arg1, arg2)
+}
+
+// SetAddrs indicates an expected call of SetAddrs.
+func (mr *MockPeerstoreMockRecorder) SetAddrs(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddrs", reflect.TypeOf((*MockPeerstore)(nil).SetAddrs), arg0, arg1, arg2)
+}
+
+// SetProtocols mocks base method.
+func (m *MockPeerstore) SetProtocols(arg0 peer.ID, arg1 ...string) error {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{arg0}
+ for _, a := range arg1 {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "SetProtocols", varargs...)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetProtocols indicates an expected call of SetProtocols.
+func (mr *MockPeerstoreMockRecorder) SetProtocols(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{arg0}, arg1...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetProtocols", reflect.TypeOf((*MockPeerstore)(nil).SetProtocols), varargs...)
+}
+
+// SupportsProtocols mocks base method.
+func (m *MockPeerstore) SupportsProtocols(arg0 peer.ID, arg1 ...string) ([]string, error) {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{arg0}
+ for _, a := range arg1 {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "SupportsProtocols", varargs...)
+ ret0, _ := ret[0].([]string)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// SupportsProtocols indicates an expected call of SupportsProtocols.
+func (mr *MockPeerstoreMockRecorder) SupportsProtocols(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{arg0}, arg1...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SupportsProtocols", reflect.TypeOf((*MockPeerstore)(nil).SupportsProtocols), varargs...)
+}
+
+// UpdateAddrs mocks base method.
+func (m *MockPeerstore) UpdateAddrs(arg0 peer.ID, arg1, arg2 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "UpdateAddrs", arg0, arg1, arg2)
+}
+
+// UpdateAddrs indicates an expected call of UpdateAddrs.
+func (mr *MockPeerstoreMockRecorder) UpdateAddrs(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAddrs", reflect.TypeOf((*MockPeerstore)(nil).UpdateAddrs), arg0, arg1, arg2)
+}
diff --git a/libs/go/libp2p_node/utils/utils.go b/libs/go/libp2p_node/utils/utils.go
index 573ad8f004..c8b533be0e 100644
--- a/libs/go/libp2p_node/utils/utils.go
+++ b/libs/go/libp2p_node/utils/utils.go
@@ -82,7 +82,7 @@ var logger zerolog.Logger = NewDefaultLogger()
// SetLoggerLevel set utils logger level
func SetLoggerLevel(lvl zerolog.Level) {
- logger.Level(lvl)
+ logger = logger.Level(lvl)
}
func ignore(err error) {
@@ -180,7 +180,6 @@ func BootstrapConnect(
if count == len(peers) {
return errors.New("failed to bootstrap: " + err.Error())
}
-
// workaround: to avoid getting `failed to find any peer in table`
// when calling dht.Provide (happens occasionally)
logger.Debug().Msg("waiting for bootstrap peers to be added to dht routing table...")
@@ -252,7 +251,7 @@ func FetchAIPublicKeyFromPubKey(publicKey crypto.PubKey) (string, error) {
return hex.EncodeToString(raw), nil
}
-// BTCPubKeyFromFetchAIPublicKey
+// BTCPubKeyFromFetchAIPublicKey from public key string
func BTCPubKeyFromFetchAIPublicKey(publicKey string) (*btcec.PublicKey, error) {
pbkBytes, err := hex.DecodeString(publicKey)
if err != nil {
@@ -268,7 +267,7 @@ func BTCPubKeyFromEthereumPublicKey(publicKey string) (*btcec.PublicKey, error)
return BTCPubKeyFromUncompressedHex(publicKey[2:])
}
-// ConvertStrEncodedSignatureToDER
+// ConvertStrEncodedSignatureToDER to convert signature to DER format
// References:
// - https://github.com/fetchai/agents-aea/blob/main/aea/crypto/cosmos.py#L258
// - https://github.com/btcsuite/btcd/blob/master/btcec/signature.go#L47
@@ -288,7 +287,7 @@ func ConvertStrEncodedSignatureToDER(signature []byte) []byte {
return sigDER
}
-// ConvertDEREncodedSignatureToStr
+// ConvertDEREncodedSignatureToStr Convert signatue from der format to string
// References:
// - https://github.com/fetchai/agents-aea/blob/main/aea/crypto/cosmos.py#L258
// - https://github.com/btcsuite/btcd/blob/master/btcec/signature.go#L47
@@ -316,14 +315,14 @@ func ParseFetchAISignature(signature string) (*btcec.Signature, error) {
// VerifyLedgerSignature verify signature of message using public key for supported ledgers
func VerifyLedgerSignature(
- ledgerId string,
+ ledgerID string,
message []byte,
signature string,
- pubkey string,
+ pubKey string,
) (bool, error) {
- verifySignature, found := verifyLedgerSignatureTable[ledgerId]
+ verifySignature, found := verifyLedgerSignatureTable[ledgerID]
if found {
- return verifySignature(message, signature, pubkey)
+ return verifySignature(message, signature, pubKey)
}
return false, errors.New("unsupported ledger")
}
@@ -371,6 +370,7 @@ func VerifyFetchAISignatureLibp2p(message []byte, signature string, pubkey strin
return verifyKey.Verify(message, sigDER)
}
+// SignFetchAI signs message with private key
func SignFetchAI(message []byte, privKey string) (string, error) {
signingKey, _, err := KeyPairFromFetchAIKey(privKey)
if err != nil {
@@ -420,8 +420,8 @@ func RecoverAddressFromEthereumSignature(message []byte, signature string) (stri
// VerifyEthereumSignatureETH verify ethereum signature using ethereum public key
func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string) (bool, error) {
- // get expected signer address
- expectedAddress, err := EthereumAddressFromPublicKey(pubkey)
+ // get ted signer address
+ tedAddress, err := EthereumAddressFromPublicKey(pubkey)
if err != nil {
return false, err
}
@@ -432,8 +432,8 @@ func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string)
return false, err
}
- if recoveredAddress != expectedAddress {
- return false, errors.New("recovered and expected addresses don't match")
+ if recoveredAddress != tedAddress {
+ return false, errors.New("recovered and ted addresses don't match")
}
return true, nil
@@ -441,13 +441,13 @@ func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string)
// KeyPairFromFetchAIKey key pair from hex encoded secp256k1 private key
func KeyPairFromFetchAIKey(key string) (crypto.PrivKey, crypto.PubKey, error) {
- pk_bytes, err := hex.DecodeString(key)
+ pkBytes, err := hex.DecodeString(key)
if err != nil {
return nil, nil, err
}
- btc_private_key, _ := btcec.PrivKeyFromBytes(btcec.S256(), pk_bytes)
- prvKey, pubKey, err := crypto.KeyPairFromStdKey(btc_private_key)
+ btcPrivateKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes)
+ prvKey, pubKey, err := crypto.KeyPairFromStdKey(btcPrivateKey)
if err != nil {
return nil, nil, err
}
@@ -457,11 +457,11 @@ func KeyPairFromFetchAIKey(key string) (crypto.PrivKey, crypto.PubKey, error) {
// AgentAddressFromPublicKey get wallet address from public key associated with ledgerId
// format from: https://github.com/fetchai/agents-aea/blob/main/aea/crypto/cosmos.py#L120
-func AgentAddressFromPublicKey(ledgerId string, publicKey string) (string, error) {
- if addressFromPublicKey, found := addressFromPublicKeyTable[ledgerId]; found {
+func AgentAddressFromPublicKey(ledgerID string, publicKey string) (string, error) {
+ if addressFromPublicKey, found := addressFromPublicKeyTable[ledgerID]; found {
return addressFromPublicKey(publicKey)
}
- return "", errors.New("unsupported ledger " + ledgerId)
+ return "", errors.New("Unsupported ledger " + ledgerID)
}
// FetchAIAddressFromPublicKey get wallet address from hex encoded secp256k1 public key
@@ -549,18 +549,18 @@ func encodeChecksumEIP55(address []byte) string {
}
// IDFromFetchAIPublicKey Get PeeID (multihash) from fetchai public key
-func IDFromFetchAIPublicKey(public_key string) (peer.ID, error) {
- b, err := hex.DecodeString(public_key)
+func IDFromFetchAIPublicKey(publicKey string) (peer.ID, error) {
+ b, err := hex.DecodeString(publicKey)
if err != nil {
return "", err
}
- pub_key, err := btcec.ParsePubKey(b, btcec.S256())
+ pubKey, err := btcec.ParsePubKey(b, btcec.S256())
if err != nil {
return "", err
}
- multihash, err := peer.IDFromPublicKey((*crypto.Secp256k1PublicKey)(pub_key))
+ multihash, err := peer.IDFromPublicKey((*crypto.Secp256k1PublicKey)(pubKey))
if err != nil {
return "", err
}
@@ -597,6 +597,7 @@ func IDFromFetchAIPublicKeyUncompressed(publicKey string) (peer.ID, error) {
return multihash, nil
}
+// FetchAIPublicKeyFromFetchAIPrivateKey get fetchai public key from fetchai private key
func FetchAIPublicKeyFromFetchAIPrivateKey(privateKey string) (string, error) {
pkBytes, err := hex.DecodeString(privateKey)
if err != nil {
@@ -613,6 +614,7 @@ func FetchAIPublicKeyFromFetchAIPrivateKey(privateKey string) (string, error) {
// WriteBytesConn send bytes to `conn`
func WriteBytesConn(conn net.Conn, data []byte) error {
+
if len(data) > math.MaxInt32 {
logger.Error().Msg("data size too large")
return errors.New("data size too large")
@@ -621,6 +623,7 @@ func WriteBytesConn(conn net.Conn, data []byte) error {
logger.Error().Msg("No data to write")
return nil
}
+
size := uint32(len(data))
buf := make([]byte, 4, 4+size)
binary.BigEndian.PutUint32(buf, size)
@@ -672,6 +675,7 @@ func ReadBytes(s network.Stream) ([]byte, error) {
if s == nil {
panic("CRITICAL can not write to nil stream")
}
+
rstream := bufio.NewReader(s)
buf := make([]byte, 4)
@@ -687,6 +691,7 @@ func ReadBytes(s network.Stream) ([]byte, error) {
if size > maxMessageSizeDelegateConnection {
return nil, errors.New("expected message size larger than maximum allowed")
}
+
//logger.Debug().Msgf("expecting %d", size)
buf = make([]byte, size)
@@ -709,6 +714,7 @@ func WriteBytes(s network.Stream, data []byte) error {
if s == nil {
panic("CRITICAL, can not write to nil stream")
}
+
wstream := bufio.NewWriter(s)
size := uint32(len(data))
@@ -723,6 +729,7 @@ func WriteBytes(s network.Stream, data []byte) error {
return err
}
+ //logger.Debug().Msgf("writing %d", len(data))
_, err = wstream.Write(data)
if err != nil {
logger.Error().
@@ -733,12 +740,73 @@ func WriteBytes(s network.Stream, data []byte) error {
if s == nil {
panic("CRITICAL, can not flush nil stream")
}
+
err = wstream.Flush()
+ return err
+}
+
+// ReadString from a network stream
+func ReadString(s network.Stream) (string, error) {
+ data, err := ReadBytes(s)
+ return string(data), err
+}
+
+// WriteEnvelope to a network stream
+func WriteEnvelope(envel *aea.Envelope, s network.Stream) error {
+ wstream := bufio.NewWriter(s)
+ data, err := proto.Marshal(envel)
+ if err != nil {
+ return err
+ }
+ size := uint32(len(data))
+
+ buf := make([]byte, 4)
+ binary.BigEndian.PutUint32(buf, size)
+ //log.Println("DEBUG writing size:", size, buf)
+ _, err = wstream.Write(buf)
+ if err != nil {
+ return err
+ }
+
+ //log.Println("DEBUG writing data:", data)
+ _, err = wstream.Write(data)
+ if err != nil {
+ return err
+ }
+
+ wstream.Flush()
+ return nil
+}
+
+// ReadEnvelope from a network stream
+func ReadEnvelope(s network.Stream) (*aea.Envelope, error) {
+ envel := &aea.Envelope{}
+ rstream := bufio.NewReader(s)
+
+ buf := make([]byte, 4)
+ _, err := io.ReadFull(rstream, buf)
+
if err != nil {
logger.Error().
Str("err", err.Error()).
- Msg("Error on stream flush")
- return err
+ Msg("while reading size")
+ return envel, err
}
- return err
+
+ size := binary.BigEndian.Uint32(buf)
+ if size > maxMessageSizeDelegateConnection {
+ return nil, errors.New("ted message size larger than maximum allowed")
+ }
+ //logger.Debug().Msgf("received size: %d %x", size, buf)
+ buf = make([]byte, size)
+ _, err = io.ReadFull(rstream, buf)
+ if err != nil {
+ logger.Error().
+ Str("err", err.Error()).
+ Msg("while reading data")
+ return envel, err
+ }
+
+ err = proto.Unmarshal(buf, envel)
+ return envel, err
}
diff --git a/libs/go/libp2p_node/utils/utils_test.go b/libs/go/libp2p_node/utils/utils_test.go
new file mode 100644
index 0000000000..f959b0cabd
--- /dev/null
+++ b/libs/go/libp2p_node/utils/utils_test.go
@@ -0,0 +1,475 @@
+/* -*- coding: utf-8 -*-
+* ------------------------------------------------------------------------------
+*
+* Copyright 2018-2021 Fetch.AI Limited
+*
+* 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.
+*
+* ------------------------------------------------------------------------------
+ */
+
+package utils
+
+import (
+ "bufio"
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "io"
+ "libp2p_node/aea"
+ mocks "libp2p_node/mocks"
+ "net"
+ "reflect"
+ "testing"
+
+ "bou.ke/monkey"
+ gomock "github.com/golang/mock/gomock"
+ "github.com/libp2p/go-libp2p-core/peer"
+ dht "github.com/libp2p/go-libp2p-kad-dht"
+ kb "github.com/libp2p/go-libp2p-kbucket"
+ ma "github.com/multiformats/go-multiaddr"
+ "github.com/rs/zerolog"
+ "github.com/stretchr/testify/assert"
+)
+
+// Crypto operations
+
+func TestEthereumCrypto(t *testing.T) {
+ //privateKey := "0xb60fe8027fb82f1a1bd6b8e66d4400f858989a2c67428a4e7f589441700339b0"
+ publicKey := "0xf753e5a9e2368e97f4db869a0d956d3ffb64672d6392670572906c786b5712ada13b6bff882951b3ba3dd65bdacc915c2b532efc3f183aa44657205c6c337225"
+ address := "0xb8d8c62d4a1999b7aea0aebBD5020244a4a9bAD8"
+ publicKeySignature := "0x304c2ba4ae7fa71295bfc2920b9c1268d574d65531f1f4d2117fc1439a45310c37ab75085a9df2a4169a4d47982b330a4387b1ded0c8881b030629db30bbaf3a1c"
+
+ addFromPublicKey, err := EthereumAddressFromPublicKey(publicKey)
+ if err != nil || addFromPublicKey != address {
+ t.Error(
+ "Error when computing address from public key or address and public key don't match",
+ )
+ }
+
+ _, err = BTCPubKeyFromEthereumPublicKey(publicKey)
+ if err != nil {
+ t.Errorf("While building BTC public key from string: %s", err.Error())
+ }
+
+ /*
+ ethSig, err := secp256k1.Sign(hashedPublicKey, hexutil.MustDecode(privateKey))
+ if err != nil {
+ t.Error(err.Error())
+ }
+ println(hexutil.Encode(ethSig))
+ hash := sha3.NewLegacyKeccak256()
+ _, err = hash.Write([]byte(publicKey))
+ if err != nil {
+ t.Error(err.Error())
+ }
+ sha3KeccakHash := hash.Sum(nil)
+ */
+
+ valid, err := VerifyEthereumSignatureETH([]byte(publicKey), publicKeySignature, publicKey)
+ if err != nil {
+ t.Error(err.Error())
+ }
+
+ if !valid {
+ t.Errorf("Signer address don't match %s", addFromPublicKey)
+ }
+}
+
+func TestFetchAICrypto(t *testing.T) {
+ publicKey := "02358e3e42a6ba15cf6b2ba6eb05f02b8893acf82b316d7dd9cda702b0892b8c71"
+ address := "fetch19dq2mkcpp6x0aypxt9c9gz6n4fqvax0x9a7t5r"
+ peerPublicKey := "027af21aff853b9d9589867ea142b0a60a9611fc8e1fae04c2f7144113fa4e938e"
+ pySigStrCanonize := "N/GOa7/m3HU8/gpLJ88VCQ6vXsdrfiiYcqnNtF+c2N9VG9ZIiycykN4hdbpbOCGrChMYZQA3G1GpozsShrUBgg=="
+
+ addressFromPublicKey, _ := FetchAIAddressFromPublicKey(publicKey)
+ if address != addressFromPublicKey {
+ t.Error("[ERR] Addresses don't match")
+ } else {
+ t.Log("[OK] Agent address matches its public key")
+ }
+
+ valid, err := VerifyFetchAISignatureBTC(
+ []byte(peerPublicKey),
+ pySigStrCanonize,
+ publicKey,
+ )
+ if !valid {
+ t.Errorf("Signature using BTC don't match %s", err.Error())
+ }
+ valid, err = VerifyFetchAISignatureLibp2p(
+ []byte(peerPublicKey),
+ pySigStrCanonize,
+ publicKey,
+ )
+ if !valid {
+ t.Errorf("Signature using LPP don't match %s", err.Error())
+ }
+}
+
+func TestSetLoggerLevel(t *testing.T) {
+ assert.Equal(t, logger.GetLevel(), zerolog.Level(0), "Initial log level is not 0")
+
+ lvl := zerolog.InfoLevel
+ SetLoggerLevel(lvl)
+
+ assert.Equal(
+ t,
+ logger.GetLevel(),
+ lvl,
+ "Waited for logger level %d but got %d",
+ lvl,
+ logger.GetLevel(),
+ )
+}
+
+func Example_ignore() {
+ ignore(errors.New("Test"))
+ // Output: IGNORED: Test
+}
+
+func TestNewDefaultLoggerWithFields(t *testing.T) {
+ fields := map[string]string{
+ "test_field": "test_value",
+ }
+ var logBuffer bytes.Buffer
+ logger := NewDefaultLoggerWithFields(fields).Output(&logBuffer)
+ logger.Info().Msg("test")
+ var jsonResult map[string]interface{}
+ err := json.Unmarshal(logBuffer.Bytes(), &jsonResult)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, jsonResult["test_field"], "test_value")
+}
+
+func TestComputeCID(t *testing.T) {
+ address := "fetch19dq2mkcpp6x0aypxt9c9gz6n4fqvax0x9a7t5r"
+ cid, err := ComputeCID(address)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, "QmZ6ryKyS9rSnesX8YnFLAmFwFuRMdHpE7pQ2V6SjXTbqM", cid.String())
+}
+
+func TestWriteBytes(t *testing.T) {
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ mockStream := mocks.NewMockStream(mockCtrl)
+ mockStream.EXPECT().Write([]byte{0, 0, 0, 5, 104, 101, 108, 108, 111}).Return(9, nil).Times(1)
+ err := WriteBytes(mockStream, []byte("hello"))
+ assert.Equal(t, nil, err)
+
+ mockStream.EXPECT().
+ Write([]byte{0, 0, 0, 4, 104, 101, 108, 108}).
+ Return(8, errors.New("oops")).
+ Times(1)
+ err = WriteBytes(mockStream, []byte("hell"))
+ assert.NotEqual(t, err, nil)
+}
+
+func TestReadBytesConn(t *testing.T) {
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ mockConn := mocks.NewMockConn(mockCtrl)
+ mockConn.EXPECT().Read(gomock.Any()).Return(4, nil).Times(2)
+ buf, err := ReadBytesConn(mockConn)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, "", string(buf))
+}
+
+func TestWriteBytesConn(t *testing.T) {
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ mockConn := mocks.NewMockConn(mockCtrl)
+ mockConn.EXPECT().Write(gomock.Any()).Return(0, nil).Times(1)
+ err := WriteBytesConn(mockConn, []byte("ABC"))
+ assert.Equal(t, nil, err)
+}
+
+func TestReadString(t *testing.T) {
+ // test ReadString and ReadBytes
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ mockStream := mocks.NewMockStream(mockCtrl)
+
+ defer monkey.UnpatchAll()
+
+ t.Run("TestReadString", func(t *testing.T) {
+ monkey.Patch(bufio.NewReader, func(reader io.Reader) *bufio.Reader {
+ return bufio.NewReaderSize(
+ bytes.NewReader([]byte{0, 0, 0, 5, 104, 101, 108, 108, 111}),
+ 100,
+ )
+ })
+ buf, err := ReadString(mockStream)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, "hello", buf)
+ })
+}
+
+func TestReadWriteEnvelope(t *testing.T) {
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ mockStream := mocks.NewMockStream(mockCtrl)
+ defer monkey.UnpatchAll()
+ address := "0xb8d8c62d4a1999b7aea0aebBD5020244a4a9bAD8"
+ buffer := bytes.NewBuffer([]byte{})
+
+ t.Run("TestWriteEnvelope", func(t *testing.T) {
+ monkey.Patch(bufio.NewWriter, func(writer io.Writer) *bufio.Writer {
+ return bufio.NewWriterSize(buffer, 100)
+ })
+ err := WriteEnvelope(&aea.Envelope{
+ To: address,
+ Sender: address,
+ }, mockStream)
+ assert.Equal(t, nil, err)
+ })
+
+ t.Run("TestReadEnvelope", func(t *testing.T) {
+ monkey.Patch(bufio.NewReader, func(reader io.Reader) *bufio.Reader {
+ return bufio.NewReaderSize(bytes.NewReader(buffer.Bytes()), 100)
+ })
+ env, err := ReadEnvelope(mockStream)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, address, env.To)
+ })
+}
+
+func TestReadWriteEnvelopeFromConnection(t *testing.T) {
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ defer monkey.UnpatchAll()
+ address := "0xb8d8c62d4a1999b7aea0aebBD5020244a4a9bAD8"
+ buffer := bytes.NewBuffer([]byte{})
+ mockConn := mocks.NewMockConn(mockCtrl)
+
+ t.Run("TestWriteEnvelope", func(t *testing.T) {
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(mockConn),
+ "Write",
+ func(_ *mocks.MockConn, b []byte) (int, error) {
+ buffer.Write(b)
+ return 0, nil
+ },
+ )
+
+ err := WriteEnvelopeConn(mockConn, &aea.Envelope{
+ To: address,
+ Sender: address,
+ })
+ assert.Equal(t, nil, err)
+ assert.NotEqual(t, 0, buffer)
+ })
+
+ t.Run("TestReadEnvelope", func(t *testing.T) {
+ monkey.Patch(ReadBytesConn, func(conn net.Conn) ([]byte, error) {
+ return buffer.Bytes()[4:], nil
+ })
+ env, err := ReadEnvelopeConn(mockConn)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, address, env.To)
+ })
+}
+
+func TestGetPeersAddrInfo(t *testing.T) {
+ addrs, err := GetPeersAddrInfo(
+ []string{
+ "/dns4/acn.fetch.ai/tcp/9001/p2p/16Uiu2HAmVWnopQAqq4pniYLw44VRvYxBUoRHqjz1Hh2SoCyjbyRW",
+ },
+ )
+ assert.Equal(t, nil, err)
+ assert.Equal(t, 1, len(addrs))
+}
+
+func TestFetchAIPublicKeyFromPubKey(t *testing.T) {
+ //(publicKey crypto.PubKey) (string, error) {
+ _, pubKey, err := KeyPairFromFetchAIKey(
+ "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc",
+ )
+ assert.Equal(t, nil, err)
+ key, err := FetchAIPublicKeyFromPubKey(pubKey)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, "03b7e977f498dce004e2614764ff576e17cc6691135497e7bcb5d3441e816ba9e1", key)
+}
+
+func TestIDFromFetchAIPublicKey(t *testing.T) {
+ _, pubKey, err := KeyPairFromFetchAIKey(
+ "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc",
+ )
+ assert.Equal(t, nil, err)
+ key, err := FetchAIPublicKeyFromPubKey(pubKey)
+ assert.Equal(t, nil, err)
+ peerID, err := IDFromFetchAIPublicKey(key)
+ assert.Equal(t, nil, err)
+ assert.NotEqual(t, 0, len(peerID))
+}
+
+func TestAgentAddressFromPublicKey(t *testing.T) {
+ address, err := AgentAddressFromPublicKey(
+ "fetchai",
+ "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc",
+ )
+ assert.Equal(t, nil, err)
+ assert.NotEqual(t, 0, len(address))
+}
+
+func TestCosmosAddressFromPublicKey(t *testing.T) {
+ address, err := CosmosAddressFromPublicKey(
+ "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc",
+ )
+ assert.Equal(t, nil, err)
+ assert.NotEqual(t, 0, len(address))
+}
+
+func TestFetchAIPublicKeyFromFetchAIPrivateKey(t *testing.T) {
+ key, err := FetchAIPublicKeyFromFetchAIPrivateKey(
+ "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc",
+ )
+ assert.Equal(t, nil, err)
+ assert.Equal(t, "03b7e977f498dce004e2614764ff576e17cc6691135497e7bcb5d3441e816ba9e1", key)
+}
+
+func TestIDFromFetchAIPublicKeyUncompressed(t *testing.T) {
+ //bad pub key
+ _, err := IDFromFetchAIPublicKeyUncompressed("some")
+ assert.NotEqual(t, nil, err)
+ // good pub key
+ id, err := IDFromFetchAIPublicKeyUncompressed(
+ "50863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6",
+ )
+ assert.Equal(t, nil, err)
+ assert.Equal(
+ t,
+ peer.ID(
+ "\x00%\b\x02\x12!\x02P\x86:\xd6J\x87\xae\x8a/\xe8<\x1a\xf1\xa8@<\xb5?S\xe4\x86\xd8Q\x1d\xad\x8a\x04\x88~[#R",
+ ),
+ id,
+ )
+}
+
+func TestSignFetchAI(t *testing.T) {
+ privKey := "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc"
+ message := []byte("somebytes")
+
+ _, pubKey, err := KeyPairFromFetchAIKey(privKey)
+ assert.Equal(t, nil, err)
+ fetchPubKey, err := FetchAIPublicKeyFromPubKey(pubKey)
+ assert.Equal(t, nil, err)
+
+ signature, err := SignFetchAI(message, privKey)
+ assert.Equal(t, nil, err)
+ assert.NotEqual(t, 0, len(signature))
+
+ isValid, err := VerifyLedgerSignature("fetchai", message, signature, fetchPubKey)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, true, isValid)
+
+}
+
+func TestBootstrapConnect(t *testing.T) {
+ ctx := context.Background()
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ defer monkey.UnpatchAll()
+ var ipfsdht *dht.IpfsDHT
+ var routingTable *kb.RoutingTable
+
+ mockPeerstore := mocks.NewMockPeerstore(mockCtrl)
+ peers := make([]peer.AddrInfo, 2)
+ var addrs []ma.Multiaddr
+ peers[0] = peer.AddrInfo{ID: peer.ID("peer1"), Addrs: addrs}
+ peers[1] = peer.AddrInfo{ID: peer.ID("peer2"), Addrs: addrs}
+
+ mockHost := mocks.NewMockHost(mockCtrl)
+
+ mockHost.EXPECT().ID().Return(peer.ID("host_id")).Times(2)
+ mockHost.EXPECT().Peerstore().Return(mockPeerstore).Times(2)
+ mockHost.EXPECT().Connect(gomock.Any(), gomock.Any()).Return(nil).Times(2)
+ mockPeerstore.EXPECT().AddAddrs(gomock.Any(), gomock.Any(), gomock.Any()).Return().Times(2)
+
+ t.Run("TestOk", func(t *testing.T) {
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(routingTable),
+ "Find",
+ func(_ *kb.RoutingTable, _ peer.ID) peer.ID {
+ return peer.ID("som peer")
+ },
+ )
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(ipfsdht),
+ "RoutingTable",
+ func(_ *dht.IpfsDHT) *kb.RoutingTable {
+ return routingTable
+ },
+ )
+
+ err := BootstrapConnect(ctx, mockHost, ipfsdht, peers)
+ assert.Equal(t, nil, err)
+ })
+
+ mockHost = mocks.NewMockHost(mockCtrl)
+
+ mockHost.EXPECT().ID().Return(peer.ID("host_id")).Times(2)
+ mockHost.EXPECT().Peerstore().Return(mockPeerstore).Times(2)
+ mockHost.EXPECT().Connect(gomock.Any(), gomock.Any()).Return(nil).Times(2)
+ mockPeerstore.EXPECT().AddAddrs(gomock.Any(), gomock.Any(), gomock.Any()).Return().Times(2)
+
+ t.Run("Test_PeersNotAdded", func(t *testing.T) {
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(routingTable),
+ "Find",
+ func(_ *kb.RoutingTable, _ peer.ID) peer.ID {
+ return peer.ID("")
+ },
+ )
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(ipfsdht),
+ "RoutingTable",
+ func(_ *dht.IpfsDHT) *kb.RoutingTable {
+ return routingTable
+ },
+ )
+
+ err := BootstrapConnect(ctx, mockHost, ipfsdht, peers)
+ assert.NotEqual(t, nil, err)
+ assert.Contains(t, err.Error(), "timeout: entry peer haven't been added to DHT")
+ })
+
+ mockHost = mocks.NewMockHost(mockCtrl)
+
+ mockHost.EXPECT().ID().Return(peer.ID("host_id")).Times(2)
+ mockHost.EXPECT().Peerstore().Return(mockPeerstore).Times(2)
+ mockHost.EXPECT().Connect(gomock.Any(), gomock.Any()).Return(errors.New("some error")).Times(2)
+ mockPeerstore.EXPECT().AddAddrs(gomock.Any(), gomock.Any(), gomock.Any()).Return().Times(2)
+
+ t.Run("Test_PeersNotConnected", func(t *testing.T) {
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(routingTable),
+ "Find",
+ func(_ *kb.RoutingTable, _ peer.ID) peer.ID {
+ return peer.ID("")
+ },
+ )
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(ipfsdht),
+ "RoutingTable",
+ func(_ *dht.IpfsDHT) *kb.RoutingTable {
+ return routingTable
+ },
+ )
+
+ err := BootstrapConnect(ctx, mockHost, ipfsdht, peers)
+ assert.NotEqual(t, nil, err)
+ assert.Equal(t, "failed to bootstrap: some error", err.Error())
+ })
+
+}
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index aae241665d..6b630ad621 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -12,6 +12,7 @@ fingerprint:
__init__.py: QmYQuLNyQ8WTjgRYAoKAzoJEb7ocKXvM2hTyK4hsGch5D6
check_dependencies.py: QmP14nkQ8senwzdPdrZJLsA6EQ7zaKKEaLGDELhT42gp1P
connection.py: QmXmCBy8AizGefC8JJo2nJZySY2kmevNgxxgMkJPvoNQRR
+ libp2p_node/Makefile: QmQ7bjtiHcW5m5xfuvA6rzrZYptGkTcrcX74wCndjuX5ZA
libp2p_node/README.md: Qmak56XnWfarVxasiaGqYQWJaNVnEAh2hsLWstuFVND98w
libp2p_node/aea/api.go: QmdFR5Rmkk2FGVDwzgHtjobjAKyLejqk2CAYBCvcF23AG7
libp2p_node/aea/envelope.pb.go: QmRfUNGpCeVJfsW3H1MzCN4pwDWgumfyWufVFp6xvUjjug
@@ -33,10 +34,15 @@ fingerprint:
libp2p_node/dht/monitoring/file.go: Qmc4QpKtjXaEFqGPeunV6TR4qR5RcMzoy8atzJH4ouBkfH
libp2p_node/dht/monitoring/prometheus.go: QmQvXjEozVPMvRjda5WGRAU5b7cfUcRZUACQkTESG7Aewu
libp2p_node/dht/monitoring/service.go: QmT47y2LHZECYcoE2uJ9QCGh3Kq8ePhYedo8dQE7X7v6YV
- libp2p_node/go.mod: QmU2MJhhvwTCfyztCei5R9LKStadFuFVUDb16s3tZwrZP8
- libp2p_node/go.sum: QmVpr925Kp8ZS7Z1iLfbjDB6NxG5BA7JczhhckzhmbYqzT
+ libp2p_node/go.mod: QmZAefiBvioX9DfJvKWibSbDGnAEo1w9LuoEVzjRoWJGWT
+ libp2p_node/go.sum: QmXELVbhPqVqSN9osMh1zpnsihPZmCC3A8tCt9maF6sjFS
libp2p_node/libp2p_node.go: QmPgMQ3g93Jqu4GAv8e7fTWbrGK8hjSp7BDrKj1EuR1WcS
- libp2p_node/utils/utils.go: QmUSw5SD3i7WhkPCVHc5ha6BhJbzk4Cf8HbyysEwUVz5zt
+ libp2p_node/mocks/mock_host.go: QmSJ7g6S2PGhC5j8xBQyrjs56hXJGEewkgFgiivyZDthbW
+ libp2p_node/mocks/mock_net.go: QmVKnkDdH8XCJ9jriEkZui4NoB36GBYF2DtfX8uCqAthMw
+ libp2p_node/mocks/mock_network.go: QmbVVvd3wrY6PnVs1rn9T9m6FD5kbmSVJLwhSxUgSLAiM5
+ libp2p_node/mocks/mock_peerstore.go: QmaPCBrwsTeWCHZoAKDzaxN6uhY3bez1karzeGeovWYwkB
+ libp2p_node/utils/utils.go: QmXxQCCsEFZH1wkzze1Z1MfcBi6rQ7ZEzACGKptQsgL8Zg
+ libp2p_node/utils/utils_test.go: QmX5bBqCwFVky6ix7pu9QNvScntr3GMDvon9cNC8dKhJiS
fingerprint_ignore_patterns: []
build_entrypoint: check_dependencies.py
connections: []
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/Makefile b/packages/fetchai/connections/p2p_libp2p/libp2p_node/Makefile
new file mode 100644
index 0000000000..ae14b117be
--- /dev/null
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/Makefile
@@ -0,0 +1,12 @@
+test:
+ go test -gcflags=-l -p 1 -timeout 0 -count 1 -covermode=atomic -coverprofile=coverage.txt -v ./...
+ go tool cover -func=coverage.txt
+
+lint:
+ golines . -w
+ golangci-lint run
+
+build:
+ go build
+install:
+ go get -v -t -d ./...
\ No newline at end of file
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.mod b/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.mod
index a5d16c054d..18898cea10 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.mod
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.mod
@@ -3,11 +3,13 @@ module libp2p_node
go 1.13
require (
+ bou.ke/monkey v1.0.2
github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4 // indirect
github.com/btcsuite/btcd v0.20.1-beta
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/dave/dst v0.26.2 // indirect
github.com/ethereum/go-ethereum v1.9.25
+ github.com/golang/mock v1.5.0
github.com/golang/protobuf v1.4.2
github.com/ipfs/go-cid v0.0.5
github.com/joho/godotenv v1.3.0
@@ -16,18 +18,21 @@ require (
github.com/libp2p/go-libp2p-circuit v0.2.2
github.com/libp2p/go-libp2p-core v0.5.3
github.com/libp2p/go-libp2p-kad-dht v0.7.11
+ github.com/libp2p/go-libp2p-kbucket v0.4.1
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/multiformats/go-multiaddr v0.2.1
github.com/multiformats/go-multihash v0.0.13
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.7.1
- github.com/rs/zerolog v1.19.0
+ github.com/rs/zerolog v1.21.0
github.com/segmentio/golines v0.0.0-20200824192126-7f30d3046793 // indirect
github.com/sirupsen/logrus v1.7.0 // indirect
+ github.com/stretchr/testify v1.5.1
golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9
golang.org/x/mod v0.4.0 // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
google.golang.org/protobuf v1.25.0
honnef.co/go/tools v0.1.4 // indirect
+
)
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.sum b/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.sum
index cb99823bb5..f108665f5e 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.sum
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/go.sum
@@ -1,3 +1,5 @@
+bou.ke/monkey v1.0.2 h1:kWcnsrCNUatbxncxR/ThdYqbytgOIArtYWqcQLQzKLI=
+bou.ke/monkey v1.0.2/go.mod h1:OqickVX3tNx6t33n1xvtTtu85YN5s6cKwVug+oHMaIA=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
@@ -129,6 +131,8 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
+github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
@@ -566,6 +570,8 @@ github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubr
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.19.0 h1:hYz4ZVdUgjXTBUmrkrw55j1nHx68LfOKIQk5IYtyScg=
github.com/rs/zerolog v1.19.0/go.mod h1:IzD0RJ65iWH0w97OQQebJEvTZYvsCUm9WVLWBQrJRjo=
+github.com/rs/zerolog v1.21.0 h1:Q3vdXlfLNT+OftyBHsU0Y445MD+8m8axjKgf2si0QcM=
+github.com/rs/zerolog v1.21.0/go.mod h1:ZPhntP/xmq1nnND05hhpAh2QMhSsA4UN3MGZ6O2J3hM=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/segmentio/golines v0.0.0-20200824192126-7f30d3046793 h1:rhR7esJSmty+9ST6Gsp7mlQHkpISw2DiYjuFaz3dRDg=
@@ -837,6 +843,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_host.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_host.go
new file mode 100644
index 0000000000..fb890fa843
--- /dev/null
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_host.go
@@ -0,0 +1,224 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: github.com/libp2p/go-libp2p-core/host (interfaces: Host)
+
+// Package mock_host is a generated GoMock package.
+package mocks
+
+import (
+ context "context"
+ reflect "reflect"
+
+ gomock "github.com/golang/mock/gomock"
+ connmgr "github.com/libp2p/go-libp2p-core/connmgr"
+ event "github.com/libp2p/go-libp2p-core/event"
+ network "github.com/libp2p/go-libp2p-core/network"
+ peer "github.com/libp2p/go-libp2p-core/peer"
+ peerstore "github.com/libp2p/go-libp2p-core/peerstore"
+ protocol "github.com/libp2p/go-libp2p-core/protocol"
+ multiaddr "github.com/multiformats/go-multiaddr"
+)
+
+// MockHost is a mock of Host interface.
+type MockHost struct {
+ ctrl *gomock.Controller
+ recorder *MockHostMockRecorder
+}
+
+// MockHostMockRecorder is the mock recorder for MockHost.
+type MockHostMockRecorder struct {
+ mock *MockHost
+}
+
+// NewMockHost creates a new mock instance.
+func NewMockHost(ctrl *gomock.Controller) *MockHost {
+ mock := &MockHost{ctrl: ctrl}
+ mock.recorder = &MockHostMockRecorder{mock}
+ return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockHost) EXPECT() *MockHostMockRecorder {
+ return m.recorder
+}
+
+// Addrs mocks base method.
+func (m *MockHost) Addrs() []multiaddr.Multiaddr {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Addrs")
+ ret0, _ := ret[0].([]multiaddr.Multiaddr)
+ return ret0
+}
+
+// Addrs indicates an expected call of Addrs.
+func (mr *MockHostMockRecorder) Addrs() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Addrs", reflect.TypeOf((*MockHost)(nil).Addrs))
+}
+
+// Close mocks base method.
+func (m *MockHost) Close() error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Close")
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Close indicates an expected call of Close.
+func (mr *MockHostMockRecorder) Close() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockHost)(nil).Close))
+}
+
+// ConnManager mocks base method.
+func (m *MockHost) ConnManager() connmgr.ConnManager {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "ConnManager")
+ ret0, _ := ret[0].(connmgr.ConnManager)
+ return ret0
+}
+
+// ConnManager indicates an expected call of ConnManager.
+func (mr *MockHostMockRecorder) ConnManager() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnManager", reflect.TypeOf((*MockHost)(nil).ConnManager))
+}
+
+// Connect mocks base method.
+func (m *MockHost) Connect(arg0 context.Context, arg1 peer.AddrInfo) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Connect", arg0, arg1)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Connect indicates an expected call of Connect.
+func (mr *MockHostMockRecorder) Connect(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockHost)(nil).Connect), arg0, arg1)
+}
+
+// EventBus mocks base method.
+func (m *MockHost) EventBus() event.Bus {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "EventBus")
+ ret0, _ := ret[0].(event.Bus)
+ return ret0
+}
+
+// EventBus indicates an expected call of EventBus.
+func (mr *MockHostMockRecorder) EventBus() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EventBus", reflect.TypeOf((*MockHost)(nil).EventBus))
+}
+
+// ID mocks base method.
+func (m *MockHost) ID() peer.ID {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "ID")
+ ret0, _ := ret[0].(peer.ID)
+ return ret0
+}
+
+// ID indicates an expected call of ID.
+func (mr *MockHostMockRecorder) ID() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockHost)(nil).ID))
+}
+
+// Mux mocks base method.
+func (m *MockHost) Mux() protocol.Switch {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Mux")
+ ret0, _ := ret[0].(protocol.Switch)
+ return ret0
+}
+
+// Mux indicates an expected call of Mux.
+func (mr *MockHostMockRecorder) Mux() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Mux", reflect.TypeOf((*MockHost)(nil).Mux))
+}
+
+// Network mocks base method.
+func (m *MockHost) Network() network.Network {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Network")
+ ret0, _ := ret[0].(network.Network)
+ return ret0
+}
+
+// Network indicates an expected call of Network.
+func (mr *MockHostMockRecorder) Network() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Network", reflect.TypeOf((*MockHost)(nil).Network))
+}
+
+// NewStream mocks base method.
+func (m *MockHost) NewStream(arg0 context.Context, arg1 peer.ID, arg2 ...protocol.ID) (network.Stream, error) {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{arg0, arg1}
+ for _, a := range arg2 {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "NewStream", varargs...)
+ ret0, _ := ret[0].(network.Stream)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// NewStream indicates an expected call of NewStream.
+func (mr *MockHostMockRecorder) NewStream(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{arg0, arg1}, arg2...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewStream", reflect.TypeOf((*MockHost)(nil).NewStream), varargs...)
+}
+
+// Peerstore mocks base method.
+func (m *MockHost) Peerstore() peerstore.Peerstore {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Peerstore")
+ ret0, _ := ret[0].(peerstore.Peerstore)
+ return ret0
+}
+
+// Peerstore indicates an expected call of Peerstore.
+func (mr *MockHostMockRecorder) Peerstore() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peerstore", reflect.TypeOf((*MockHost)(nil).Peerstore))
+}
+
+// RemoveStreamHandler mocks base method.
+func (m *MockHost) RemoveStreamHandler(arg0 protocol.ID) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "RemoveStreamHandler", arg0)
+}
+
+// RemoveStreamHandler indicates an expected call of RemoveStreamHandler.
+func (mr *MockHostMockRecorder) RemoveStreamHandler(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveStreamHandler", reflect.TypeOf((*MockHost)(nil).RemoveStreamHandler), arg0)
+}
+
+// SetStreamHandler mocks base method.
+func (m *MockHost) SetStreamHandler(arg0 protocol.ID, arg1 network.StreamHandler) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "SetStreamHandler", arg0, arg1)
+}
+
+// SetStreamHandler indicates an expected call of SetStreamHandler.
+func (mr *MockHostMockRecorder) SetStreamHandler(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetStreamHandler", reflect.TypeOf((*MockHost)(nil).SetStreamHandler), arg0, arg1)
+}
+
+// SetStreamHandlerMatch mocks base method.
+func (m *MockHost) SetStreamHandlerMatch(arg0 protocol.ID, arg1 func(string) bool, arg2 network.StreamHandler) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "SetStreamHandlerMatch", arg0, arg1, arg2)
+}
+
+// SetStreamHandlerMatch indicates an expected call of SetStreamHandlerMatch.
+func (mr *MockHostMockRecorder) SetStreamHandlerMatch(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetStreamHandlerMatch", reflect.TypeOf((*MockHost)(nil).SetStreamHandlerMatch), arg0, arg1, arg2)
+}
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_net.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_net.go
new file mode 100644
index 0000000000..2f6b440075
--- /dev/null
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_net.go
@@ -0,0 +1,150 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: net (interfaces: Conn)
+
+// Package mock_net is a generated GoMock package.
+package mocks
+
+import (
+ net "net"
+ reflect "reflect"
+ time "time"
+
+ gomock "github.com/golang/mock/gomock"
+)
+
+// MockConn is a mock of Conn interface.
+type MockConn struct {
+ ctrl *gomock.Controller
+ recorder *MockConnMockRecorder
+}
+
+// MockConnMockRecorder is the mock recorder for MockConn.
+type MockConnMockRecorder struct {
+ mock *MockConn
+}
+
+// NewMockConn creates a new mock instance.
+func NewMockConn(ctrl *gomock.Controller) *MockConn {
+ mock := &MockConn{ctrl: ctrl}
+ mock.recorder = &MockConnMockRecorder{mock}
+ return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockConn) EXPECT() *MockConnMockRecorder {
+ return m.recorder
+}
+
+// Close mocks base method.
+func (m *MockConn) Close() error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Close")
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Close indicates an expected call of Close.
+func (mr *MockConnMockRecorder) Close() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockConn)(nil).Close))
+}
+
+// LocalAddr mocks base method.
+func (m *MockConn) LocalAddr() net.Addr {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "LocalAddr")
+ ret0, _ := ret[0].(net.Addr)
+ return ret0
+}
+
+// LocalAddr indicates an expected call of LocalAddr.
+func (mr *MockConnMockRecorder) LocalAddr() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LocalAddr", reflect.TypeOf((*MockConn)(nil).LocalAddr))
+}
+
+// Read mocks base method.
+func (m *MockConn) Read(arg0 []byte) (int, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Read", arg0)
+ ret0, _ := ret[0].(int)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// Read indicates an expected call of Read.
+func (mr *MockConnMockRecorder) Read(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockConn)(nil).Read), arg0)
+}
+
+// RemoteAddr mocks base method.
+func (m *MockConn) RemoteAddr() net.Addr {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "RemoteAddr")
+ ret0, _ := ret[0].(net.Addr)
+ return ret0
+}
+
+// RemoteAddr indicates an expected call of RemoteAddr.
+func (mr *MockConnMockRecorder) RemoteAddr() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockConn)(nil).RemoteAddr))
+}
+
+// SetDeadline mocks base method.
+func (m *MockConn) SetDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetDeadline indicates an expected call of SetDeadline.
+func (mr *MockConnMockRecorder) SetDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockConn)(nil).SetDeadline), arg0)
+}
+
+// SetReadDeadline mocks base method.
+func (m *MockConn) SetReadDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetReadDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetReadDeadline indicates an expected call of SetReadDeadline.
+func (mr *MockConnMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockConn)(nil).SetReadDeadline), arg0)
+}
+
+// SetWriteDeadline mocks base method.
+func (m *MockConn) SetWriteDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetWriteDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetWriteDeadline indicates an expected call of SetWriteDeadline.
+func (mr *MockConnMockRecorder) SetWriteDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockConn)(nil).SetWriteDeadline), arg0)
+}
+
+// Write mocks base method.
+func (m *MockConn) Write(arg0 []byte) (int, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Write", arg0)
+ ret0, _ := ret[0].(int)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// Write indicates an expected call of Write.
+func (mr *MockConnMockRecorder) Write(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockConn)(nil).Write), arg0)
+}
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_network.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_network.go
new file mode 100644
index 0000000000..ab38a029fc
--- /dev/null
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_network.go
@@ -0,0 +1,191 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: github.com/libp2p/go-libp2p-core/network (interfaces: Stream)
+
+// Package mock_network is a generated GoMock package.
+package mocks
+
+import (
+ reflect "reflect"
+ time "time"
+
+ gomock "github.com/golang/mock/gomock"
+ network "github.com/libp2p/go-libp2p-core/network"
+ protocol "github.com/libp2p/go-libp2p-core/protocol"
+)
+
+// MockStream is a mock of Stream interface.
+type MockStream struct {
+ ctrl *gomock.Controller
+ recorder *MockStreamMockRecorder
+}
+
+// MockStreamMockRecorder is the mock recorder for MockStream.
+type MockStreamMockRecorder struct {
+ mock *MockStream
+}
+
+// NewMockStream creates a new mock instance.
+func NewMockStream(ctrl *gomock.Controller) *MockStream {
+ mock := &MockStream{ctrl: ctrl}
+ mock.recorder = &MockStreamMockRecorder{mock}
+ return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockStream) EXPECT() *MockStreamMockRecorder {
+ return m.recorder
+}
+
+// Close mocks base method.
+func (m *MockStream) Close() error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Close")
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Close indicates an expected call of Close.
+func (mr *MockStreamMockRecorder) Close() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockStream)(nil).Close))
+}
+
+// Conn mocks base method.
+func (m *MockStream) Conn() network.Conn {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Conn")
+ ret0, _ := ret[0].(network.Conn)
+ return ret0
+}
+
+// Conn indicates an expected call of Conn.
+func (mr *MockStreamMockRecorder) Conn() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Conn", reflect.TypeOf((*MockStream)(nil).Conn))
+}
+
+// Protocol mocks base method.
+func (m *MockStream) Protocol() protocol.ID {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Protocol")
+ ret0, _ := ret[0].(protocol.ID)
+ return ret0
+}
+
+// Protocol indicates an expected call of Protocol.
+func (mr *MockStreamMockRecorder) Protocol() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Protocol", reflect.TypeOf((*MockStream)(nil).Protocol))
+}
+
+// Read mocks base method.
+func (m *MockStream) Read(arg0 []byte) (int, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Read", arg0)
+ ret0, _ := ret[0].(int)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// Read indicates an expected call of Read.
+func (mr *MockStreamMockRecorder) Read(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStream)(nil).Read), arg0)
+}
+
+// Reset mocks base method.
+func (m *MockStream) Reset() error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Reset")
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Reset indicates an expected call of Reset.
+func (mr *MockStreamMockRecorder) Reset() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reset", reflect.TypeOf((*MockStream)(nil).Reset))
+}
+
+// SetDeadline mocks base method.
+func (m *MockStream) SetDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetDeadline indicates an expected call of SetDeadline.
+func (mr *MockStreamMockRecorder) SetDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetDeadline", reflect.TypeOf((*MockStream)(nil).SetDeadline), arg0)
+}
+
+// SetProtocol mocks base method.
+func (m *MockStream) SetProtocol(arg0 protocol.ID) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "SetProtocol", arg0)
+}
+
+// SetProtocol indicates an expected call of SetProtocol.
+func (mr *MockStreamMockRecorder) SetProtocol(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetProtocol", reflect.TypeOf((*MockStream)(nil).SetProtocol), arg0)
+}
+
+// SetReadDeadline mocks base method.
+func (m *MockStream) SetReadDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetReadDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetReadDeadline indicates an expected call of SetReadDeadline.
+func (mr *MockStreamMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStream)(nil).SetReadDeadline), arg0)
+}
+
+// SetWriteDeadline mocks base method.
+func (m *MockStream) SetWriteDeadline(arg0 time.Time) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "SetWriteDeadline", arg0)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetWriteDeadline indicates an expected call of SetWriteDeadline.
+func (mr *MockStreamMockRecorder) SetWriteDeadline(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWriteDeadline", reflect.TypeOf((*MockStream)(nil).SetWriteDeadline), arg0)
+}
+
+// Stat mocks base method.
+func (m *MockStream) Stat() network.Stat {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Stat")
+ ret0, _ := ret[0].(network.Stat)
+ return ret0
+}
+
+// Stat indicates an expected call of Stat.
+func (mr *MockStreamMockRecorder) Stat() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stat", reflect.TypeOf((*MockStream)(nil).Stat))
+}
+
+// Write mocks base method.
+func (m *MockStream) Write(arg0 []byte) (int, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Write", arg0)
+ ret0, _ := ret[0].(int)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// Write indicates an expected call of Write.
+func (mr *MockStreamMockRecorder) Write(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStream)(nil).Write), arg0)
+}
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_peerstore.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_peerstore.go
new file mode 100644
index 0000000000..c1e2568dcc
--- /dev/null
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/mocks/mock_peerstore.go
@@ -0,0 +1,412 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: github.com/libp2p/go-libp2p-core/peerstore (interfaces: Peerstore)
+
+// Package mock_peerstore is a generated GoMock package.
+package mocks
+
+import (
+ context "context"
+ reflect "reflect"
+ time "time"
+
+ gomock "github.com/golang/mock/gomock"
+ crypto "github.com/libp2p/go-libp2p-core/crypto"
+ peer "github.com/libp2p/go-libp2p-core/peer"
+ multiaddr "github.com/multiformats/go-multiaddr"
+)
+
+// MockPeerstore is a mock of Peerstore interface.
+type MockPeerstore struct {
+ ctrl *gomock.Controller
+ recorder *MockPeerstoreMockRecorder
+}
+
+// MockPeerstoreMockRecorder is the mock recorder for MockPeerstore.
+type MockPeerstoreMockRecorder struct {
+ mock *MockPeerstore
+}
+
+// NewMockPeerstore creates a new mock instance.
+func NewMockPeerstore(ctrl *gomock.Controller) *MockPeerstore {
+ mock := &MockPeerstore{ctrl: ctrl}
+ mock.recorder = &MockPeerstoreMockRecorder{mock}
+ return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockPeerstore) EXPECT() *MockPeerstoreMockRecorder {
+ return m.recorder
+}
+
+// AddAddr mocks base method.
+func (m *MockPeerstore) AddAddr(arg0 peer.ID, arg1 multiaddr.Multiaddr, arg2 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "AddAddr", arg0, arg1, arg2)
+}
+
+// AddAddr indicates an expected call of AddAddr.
+func (mr *MockPeerstoreMockRecorder) AddAddr(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAddr", reflect.TypeOf((*MockPeerstore)(nil).AddAddr), arg0, arg1, arg2)
+}
+
+// AddAddrs mocks base method.
+func (m *MockPeerstore) AddAddrs(arg0 peer.ID, arg1 []multiaddr.Multiaddr, arg2 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "AddAddrs", arg0, arg1, arg2)
+}
+
+// AddAddrs indicates an expected call of AddAddrs.
+func (mr *MockPeerstoreMockRecorder) AddAddrs(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddAddrs", reflect.TypeOf((*MockPeerstore)(nil).AddAddrs), arg0, arg1, arg2)
+}
+
+// AddPrivKey mocks base method.
+func (m *MockPeerstore) AddPrivKey(arg0 peer.ID, arg1 crypto.PrivKey) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "AddPrivKey", arg0, arg1)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// AddPrivKey indicates an expected call of AddPrivKey.
+func (mr *MockPeerstoreMockRecorder) AddPrivKey(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPrivKey", reflect.TypeOf((*MockPeerstore)(nil).AddPrivKey), arg0, arg1)
+}
+
+// AddProtocols mocks base method.
+func (m *MockPeerstore) AddProtocols(arg0 peer.ID, arg1 ...string) error {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{arg0}
+ for _, a := range arg1 {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "AddProtocols", varargs...)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// AddProtocols indicates an expected call of AddProtocols.
+func (mr *MockPeerstoreMockRecorder) AddProtocols(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{arg0}, arg1...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProtocols", reflect.TypeOf((*MockPeerstore)(nil).AddProtocols), varargs...)
+}
+
+// AddPubKey mocks base method.
+func (m *MockPeerstore) AddPubKey(arg0 peer.ID, arg1 crypto.PubKey) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "AddPubKey", arg0, arg1)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// AddPubKey indicates an expected call of AddPubKey.
+func (mr *MockPeerstoreMockRecorder) AddPubKey(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPubKey", reflect.TypeOf((*MockPeerstore)(nil).AddPubKey), arg0, arg1)
+}
+
+// AddrStream mocks base method.
+func (m *MockPeerstore) AddrStream(arg0 context.Context, arg1 peer.ID) <-chan multiaddr.Multiaddr {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "AddrStream", arg0, arg1)
+ ret0, _ := ret[0].(<-chan multiaddr.Multiaddr)
+ return ret0
+}
+
+// AddrStream indicates an expected call of AddrStream.
+func (mr *MockPeerstoreMockRecorder) AddrStream(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddrStream", reflect.TypeOf((*MockPeerstore)(nil).AddrStream), arg0, arg1)
+}
+
+// Addrs mocks base method.
+func (m *MockPeerstore) Addrs(arg0 peer.ID) []multiaddr.Multiaddr {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Addrs", arg0)
+ ret0, _ := ret[0].([]multiaddr.Multiaddr)
+ return ret0
+}
+
+// Addrs indicates an expected call of Addrs.
+func (mr *MockPeerstoreMockRecorder) Addrs(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Addrs", reflect.TypeOf((*MockPeerstore)(nil).Addrs), arg0)
+}
+
+// ClearAddrs mocks base method.
+func (m *MockPeerstore) ClearAddrs(arg0 peer.ID) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "ClearAddrs", arg0)
+}
+
+// ClearAddrs indicates an expected call of ClearAddrs.
+func (mr *MockPeerstoreMockRecorder) ClearAddrs(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClearAddrs", reflect.TypeOf((*MockPeerstore)(nil).ClearAddrs), arg0)
+}
+
+// Close mocks base method.
+func (m *MockPeerstore) Close() error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Close")
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Close indicates an expected call of Close.
+func (mr *MockPeerstoreMockRecorder) Close() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPeerstore)(nil).Close))
+}
+
+// Get mocks base method.
+func (m *MockPeerstore) Get(arg0 peer.ID, arg1 string) (interface{}, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Get", arg0, arg1)
+ ret0, _ := ret[0].(interface{})
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// Get indicates an expected call of Get.
+func (mr *MockPeerstoreMockRecorder) Get(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockPeerstore)(nil).Get), arg0, arg1)
+}
+
+// GetProtocols mocks base method.
+func (m *MockPeerstore) GetProtocols(arg0 peer.ID) ([]string, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetProtocols", arg0)
+ ret0, _ := ret[0].([]string)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetProtocols indicates an expected call of GetProtocols.
+func (mr *MockPeerstoreMockRecorder) GetProtocols(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetProtocols", reflect.TypeOf((*MockPeerstore)(nil).GetProtocols), arg0)
+}
+
+// LatencyEWMA mocks base method.
+func (m *MockPeerstore) LatencyEWMA(arg0 peer.ID) time.Duration {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "LatencyEWMA", arg0)
+ ret0, _ := ret[0].(time.Duration)
+ return ret0
+}
+
+// LatencyEWMA indicates an expected call of LatencyEWMA.
+func (mr *MockPeerstoreMockRecorder) LatencyEWMA(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LatencyEWMA", reflect.TypeOf((*MockPeerstore)(nil).LatencyEWMA), arg0)
+}
+
+// PeerInfo mocks base method.
+func (m *MockPeerstore) PeerInfo(arg0 peer.ID) peer.AddrInfo {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "PeerInfo", arg0)
+ ret0, _ := ret[0].(peer.AddrInfo)
+ return ret0
+}
+
+// PeerInfo indicates an expected call of PeerInfo.
+func (mr *MockPeerstoreMockRecorder) PeerInfo(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerInfo", reflect.TypeOf((*MockPeerstore)(nil).PeerInfo), arg0)
+}
+
+// Peers mocks base method.
+func (m *MockPeerstore) Peers() peer.IDSlice {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Peers")
+ ret0, _ := ret[0].(peer.IDSlice)
+ return ret0
+}
+
+// Peers indicates an expected call of Peers.
+func (mr *MockPeerstoreMockRecorder) Peers() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peers", reflect.TypeOf((*MockPeerstore)(nil).Peers))
+}
+
+// PeersWithAddrs mocks base method.
+func (m *MockPeerstore) PeersWithAddrs() peer.IDSlice {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "PeersWithAddrs")
+ ret0, _ := ret[0].(peer.IDSlice)
+ return ret0
+}
+
+// PeersWithAddrs indicates an expected call of PeersWithAddrs.
+func (mr *MockPeerstoreMockRecorder) PeersWithAddrs() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeersWithAddrs", reflect.TypeOf((*MockPeerstore)(nil).PeersWithAddrs))
+}
+
+// PeersWithKeys mocks base method.
+func (m *MockPeerstore) PeersWithKeys() peer.IDSlice {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "PeersWithKeys")
+ ret0, _ := ret[0].(peer.IDSlice)
+ return ret0
+}
+
+// PeersWithKeys indicates an expected call of PeersWithKeys.
+func (mr *MockPeerstoreMockRecorder) PeersWithKeys() *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeersWithKeys", reflect.TypeOf((*MockPeerstore)(nil).PeersWithKeys))
+}
+
+// PrivKey mocks base method.
+func (m *MockPeerstore) PrivKey(arg0 peer.ID) crypto.PrivKey {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "PrivKey", arg0)
+ ret0, _ := ret[0].(crypto.PrivKey)
+ return ret0
+}
+
+// PrivKey indicates an expected call of PrivKey.
+func (mr *MockPeerstoreMockRecorder) PrivKey(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrivKey", reflect.TypeOf((*MockPeerstore)(nil).PrivKey), arg0)
+}
+
+// PubKey mocks base method.
+func (m *MockPeerstore) PubKey(arg0 peer.ID) crypto.PubKey {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "PubKey", arg0)
+ ret0, _ := ret[0].(crypto.PubKey)
+ return ret0
+}
+
+// PubKey indicates an expected call of PubKey.
+func (mr *MockPeerstoreMockRecorder) PubKey(arg0 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PubKey", reflect.TypeOf((*MockPeerstore)(nil).PubKey), arg0)
+}
+
+// Put mocks base method.
+func (m *MockPeerstore) Put(arg0 peer.ID, arg1 string, arg2 interface{}) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "Put", arg0, arg1, arg2)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// Put indicates an expected call of Put.
+func (mr *MockPeerstoreMockRecorder) Put(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockPeerstore)(nil).Put), arg0, arg1, arg2)
+}
+
+// RecordLatency mocks base method.
+func (m *MockPeerstore) RecordLatency(arg0 peer.ID, arg1 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "RecordLatency", arg0, arg1)
+}
+
+// RecordLatency indicates an expected call of RecordLatency.
+func (mr *MockPeerstoreMockRecorder) RecordLatency(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecordLatency", reflect.TypeOf((*MockPeerstore)(nil).RecordLatency), arg0, arg1)
+}
+
+// RemoveProtocols mocks base method.
+func (m *MockPeerstore) RemoveProtocols(arg0 peer.ID, arg1 ...string) error {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{arg0}
+ for _, a := range arg1 {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "RemoveProtocols", varargs...)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// RemoveProtocols indicates an expected call of RemoveProtocols.
+func (mr *MockPeerstoreMockRecorder) RemoveProtocols(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{arg0}, arg1...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveProtocols", reflect.TypeOf((*MockPeerstore)(nil).RemoveProtocols), varargs...)
+}
+
+// SetAddr mocks base method.
+func (m *MockPeerstore) SetAddr(arg0 peer.ID, arg1 multiaddr.Multiaddr, arg2 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "SetAddr", arg0, arg1, arg2)
+}
+
+// SetAddr indicates an expected call of SetAddr.
+func (mr *MockPeerstoreMockRecorder) SetAddr(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddr", reflect.TypeOf((*MockPeerstore)(nil).SetAddr), arg0, arg1, arg2)
+}
+
+// SetAddrs mocks base method.
+func (m *MockPeerstore) SetAddrs(arg0 peer.ID, arg1 []multiaddr.Multiaddr, arg2 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "SetAddrs", arg0, arg1, arg2)
+}
+
+// SetAddrs indicates an expected call of SetAddrs.
+func (mr *MockPeerstoreMockRecorder) SetAddrs(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetAddrs", reflect.TypeOf((*MockPeerstore)(nil).SetAddrs), arg0, arg1, arg2)
+}
+
+// SetProtocols mocks base method.
+func (m *MockPeerstore) SetProtocols(arg0 peer.ID, arg1 ...string) error {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{arg0}
+ for _, a := range arg1 {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "SetProtocols", varargs...)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// SetProtocols indicates an expected call of SetProtocols.
+func (mr *MockPeerstoreMockRecorder) SetProtocols(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{arg0}, arg1...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetProtocols", reflect.TypeOf((*MockPeerstore)(nil).SetProtocols), varargs...)
+}
+
+// SupportsProtocols mocks base method.
+func (m *MockPeerstore) SupportsProtocols(arg0 peer.ID, arg1 ...string) ([]string, error) {
+ m.ctrl.T.Helper()
+ varargs := []interface{}{arg0}
+ for _, a := range arg1 {
+ varargs = append(varargs, a)
+ }
+ ret := m.ctrl.Call(m, "SupportsProtocols", varargs...)
+ ret0, _ := ret[0].([]string)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// SupportsProtocols indicates an expected call of SupportsProtocols.
+func (mr *MockPeerstoreMockRecorder) SupportsProtocols(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ varargs := append([]interface{}{arg0}, arg1...)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SupportsProtocols", reflect.TypeOf((*MockPeerstore)(nil).SupportsProtocols), varargs...)
+}
+
+// UpdateAddrs mocks base method.
+func (m *MockPeerstore) UpdateAddrs(arg0 peer.ID, arg1, arg2 time.Duration) {
+ m.ctrl.T.Helper()
+ m.ctrl.Call(m, "UpdateAddrs", arg0, arg1, arg2)
+}
+
+// UpdateAddrs indicates an expected call of UpdateAddrs.
+func (mr *MockPeerstoreMockRecorder) UpdateAddrs(arg0, arg1, arg2 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAddrs", reflect.TypeOf((*MockPeerstore)(nil).UpdateAddrs), arg0, arg1, arg2)
+}
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
index 573ad8f004..c8b533be0e 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
@@ -82,7 +82,7 @@ var logger zerolog.Logger = NewDefaultLogger()
// SetLoggerLevel set utils logger level
func SetLoggerLevel(lvl zerolog.Level) {
- logger.Level(lvl)
+ logger = logger.Level(lvl)
}
func ignore(err error) {
@@ -180,7 +180,6 @@ func BootstrapConnect(
if count == len(peers) {
return errors.New("failed to bootstrap: " + err.Error())
}
-
// workaround: to avoid getting `failed to find any peer in table`
// when calling dht.Provide (happens occasionally)
logger.Debug().Msg("waiting for bootstrap peers to be added to dht routing table...")
@@ -252,7 +251,7 @@ func FetchAIPublicKeyFromPubKey(publicKey crypto.PubKey) (string, error) {
return hex.EncodeToString(raw), nil
}
-// BTCPubKeyFromFetchAIPublicKey
+// BTCPubKeyFromFetchAIPublicKey from public key string
func BTCPubKeyFromFetchAIPublicKey(publicKey string) (*btcec.PublicKey, error) {
pbkBytes, err := hex.DecodeString(publicKey)
if err != nil {
@@ -268,7 +267,7 @@ func BTCPubKeyFromEthereumPublicKey(publicKey string) (*btcec.PublicKey, error)
return BTCPubKeyFromUncompressedHex(publicKey[2:])
}
-// ConvertStrEncodedSignatureToDER
+// ConvertStrEncodedSignatureToDER to convert signature to DER format
// References:
// - https://github.com/fetchai/agents-aea/blob/main/aea/crypto/cosmos.py#L258
// - https://github.com/btcsuite/btcd/blob/master/btcec/signature.go#L47
@@ -288,7 +287,7 @@ func ConvertStrEncodedSignatureToDER(signature []byte) []byte {
return sigDER
}
-// ConvertDEREncodedSignatureToStr
+// ConvertDEREncodedSignatureToStr Convert signatue from der format to string
// References:
// - https://github.com/fetchai/agents-aea/blob/main/aea/crypto/cosmos.py#L258
// - https://github.com/btcsuite/btcd/blob/master/btcec/signature.go#L47
@@ -316,14 +315,14 @@ func ParseFetchAISignature(signature string) (*btcec.Signature, error) {
// VerifyLedgerSignature verify signature of message using public key for supported ledgers
func VerifyLedgerSignature(
- ledgerId string,
+ ledgerID string,
message []byte,
signature string,
- pubkey string,
+ pubKey string,
) (bool, error) {
- verifySignature, found := verifyLedgerSignatureTable[ledgerId]
+ verifySignature, found := verifyLedgerSignatureTable[ledgerID]
if found {
- return verifySignature(message, signature, pubkey)
+ return verifySignature(message, signature, pubKey)
}
return false, errors.New("unsupported ledger")
}
@@ -371,6 +370,7 @@ func VerifyFetchAISignatureLibp2p(message []byte, signature string, pubkey strin
return verifyKey.Verify(message, sigDER)
}
+// SignFetchAI signs message with private key
func SignFetchAI(message []byte, privKey string) (string, error) {
signingKey, _, err := KeyPairFromFetchAIKey(privKey)
if err != nil {
@@ -420,8 +420,8 @@ func RecoverAddressFromEthereumSignature(message []byte, signature string) (stri
// VerifyEthereumSignatureETH verify ethereum signature using ethereum public key
func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string) (bool, error) {
- // get expected signer address
- expectedAddress, err := EthereumAddressFromPublicKey(pubkey)
+ // get ted signer address
+ tedAddress, err := EthereumAddressFromPublicKey(pubkey)
if err != nil {
return false, err
}
@@ -432,8 +432,8 @@ func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string)
return false, err
}
- if recoveredAddress != expectedAddress {
- return false, errors.New("recovered and expected addresses don't match")
+ if recoveredAddress != tedAddress {
+ return false, errors.New("recovered and ted addresses don't match")
}
return true, nil
@@ -441,13 +441,13 @@ func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string)
// KeyPairFromFetchAIKey key pair from hex encoded secp256k1 private key
func KeyPairFromFetchAIKey(key string) (crypto.PrivKey, crypto.PubKey, error) {
- pk_bytes, err := hex.DecodeString(key)
+ pkBytes, err := hex.DecodeString(key)
if err != nil {
return nil, nil, err
}
- btc_private_key, _ := btcec.PrivKeyFromBytes(btcec.S256(), pk_bytes)
- prvKey, pubKey, err := crypto.KeyPairFromStdKey(btc_private_key)
+ btcPrivateKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes)
+ prvKey, pubKey, err := crypto.KeyPairFromStdKey(btcPrivateKey)
if err != nil {
return nil, nil, err
}
@@ -457,11 +457,11 @@ func KeyPairFromFetchAIKey(key string) (crypto.PrivKey, crypto.PubKey, error) {
// AgentAddressFromPublicKey get wallet address from public key associated with ledgerId
// format from: https://github.com/fetchai/agents-aea/blob/main/aea/crypto/cosmos.py#L120
-func AgentAddressFromPublicKey(ledgerId string, publicKey string) (string, error) {
- if addressFromPublicKey, found := addressFromPublicKeyTable[ledgerId]; found {
+func AgentAddressFromPublicKey(ledgerID string, publicKey string) (string, error) {
+ if addressFromPublicKey, found := addressFromPublicKeyTable[ledgerID]; found {
return addressFromPublicKey(publicKey)
}
- return "", errors.New("unsupported ledger " + ledgerId)
+ return "", errors.New("Unsupported ledger " + ledgerID)
}
// FetchAIAddressFromPublicKey get wallet address from hex encoded secp256k1 public key
@@ -549,18 +549,18 @@ func encodeChecksumEIP55(address []byte) string {
}
// IDFromFetchAIPublicKey Get PeeID (multihash) from fetchai public key
-func IDFromFetchAIPublicKey(public_key string) (peer.ID, error) {
- b, err := hex.DecodeString(public_key)
+func IDFromFetchAIPublicKey(publicKey string) (peer.ID, error) {
+ b, err := hex.DecodeString(publicKey)
if err != nil {
return "", err
}
- pub_key, err := btcec.ParsePubKey(b, btcec.S256())
+ pubKey, err := btcec.ParsePubKey(b, btcec.S256())
if err != nil {
return "", err
}
- multihash, err := peer.IDFromPublicKey((*crypto.Secp256k1PublicKey)(pub_key))
+ multihash, err := peer.IDFromPublicKey((*crypto.Secp256k1PublicKey)(pubKey))
if err != nil {
return "", err
}
@@ -597,6 +597,7 @@ func IDFromFetchAIPublicKeyUncompressed(publicKey string) (peer.ID, error) {
return multihash, nil
}
+// FetchAIPublicKeyFromFetchAIPrivateKey get fetchai public key from fetchai private key
func FetchAIPublicKeyFromFetchAIPrivateKey(privateKey string) (string, error) {
pkBytes, err := hex.DecodeString(privateKey)
if err != nil {
@@ -613,6 +614,7 @@ func FetchAIPublicKeyFromFetchAIPrivateKey(privateKey string) (string, error) {
// WriteBytesConn send bytes to `conn`
func WriteBytesConn(conn net.Conn, data []byte) error {
+
if len(data) > math.MaxInt32 {
logger.Error().Msg("data size too large")
return errors.New("data size too large")
@@ -621,6 +623,7 @@ func WriteBytesConn(conn net.Conn, data []byte) error {
logger.Error().Msg("No data to write")
return nil
}
+
size := uint32(len(data))
buf := make([]byte, 4, 4+size)
binary.BigEndian.PutUint32(buf, size)
@@ -672,6 +675,7 @@ func ReadBytes(s network.Stream) ([]byte, error) {
if s == nil {
panic("CRITICAL can not write to nil stream")
}
+
rstream := bufio.NewReader(s)
buf := make([]byte, 4)
@@ -687,6 +691,7 @@ func ReadBytes(s network.Stream) ([]byte, error) {
if size > maxMessageSizeDelegateConnection {
return nil, errors.New("expected message size larger than maximum allowed")
}
+
//logger.Debug().Msgf("expecting %d", size)
buf = make([]byte, size)
@@ -709,6 +714,7 @@ func WriteBytes(s network.Stream, data []byte) error {
if s == nil {
panic("CRITICAL, can not write to nil stream")
}
+
wstream := bufio.NewWriter(s)
size := uint32(len(data))
@@ -723,6 +729,7 @@ func WriteBytes(s network.Stream, data []byte) error {
return err
}
+ //logger.Debug().Msgf("writing %d", len(data))
_, err = wstream.Write(data)
if err != nil {
logger.Error().
@@ -733,12 +740,73 @@ func WriteBytes(s network.Stream, data []byte) error {
if s == nil {
panic("CRITICAL, can not flush nil stream")
}
+
err = wstream.Flush()
+ return err
+}
+
+// ReadString from a network stream
+func ReadString(s network.Stream) (string, error) {
+ data, err := ReadBytes(s)
+ return string(data), err
+}
+
+// WriteEnvelope to a network stream
+func WriteEnvelope(envel *aea.Envelope, s network.Stream) error {
+ wstream := bufio.NewWriter(s)
+ data, err := proto.Marshal(envel)
+ if err != nil {
+ return err
+ }
+ size := uint32(len(data))
+
+ buf := make([]byte, 4)
+ binary.BigEndian.PutUint32(buf, size)
+ //log.Println("DEBUG writing size:", size, buf)
+ _, err = wstream.Write(buf)
+ if err != nil {
+ return err
+ }
+
+ //log.Println("DEBUG writing data:", data)
+ _, err = wstream.Write(data)
+ if err != nil {
+ return err
+ }
+
+ wstream.Flush()
+ return nil
+}
+
+// ReadEnvelope from a network stream
+func ReadEnvelope(s network.Stream) (*aea.Envelope, error) {
+ envel := &aea.Envelope{}
+ rstream := bufio.NewReader(s)
+
+ buf := make([]byte, 4)
+ _, err := io.ReadFull(rstream, buf)
+
if err != nil {
logger.Error().
Str("err", err.Error()).
- Msg("Error on stream flush")
- return err
+ Msg("while reading size")
+ return envel, err
}
- return err
+
+ size := binary.BigEndian.Uint32(buf)
+ if size > maxMessageSizeDelegateConnection {
+ return nil, errors.New("ted message size larger than maximum allowed")
+ }
+ //logger.Debug().Msgf("received size: %d %x", size, buf)
+ buf = make([]byte, size)
+ _, err = io.ReadFull(rstream, buf)
+ if err != nil {
+ logger.Error().
+ Str("err", err.Error()).
+ Msg("while reading data")
+ return envel, err
+ }
+
+ err = proto.Unmarshal(buf, envel)
+ return envel, err
}
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils_test.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils_test.go
new file mode 100644
index 0000000000..f959b0cabd
--- /dev/null
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils_test.go
@@ -0,0 +1,475 @@
+/* -*- coding: utf-8 -*-
+* ------------------------------------------------------------------------------
+*
+* Copyright 2018-2021 Fetch.AI Limited
+*
+* 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.
+*
+* ------------------------------------------------------------------------------
+ */
+
+package utils
+
+import (
+ "bufio"
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "io"
+ "libp2p_node/aea"
+ mocks "libp2p_node/mocks"
+ "net"
+ "reflect"
+ "testing"
+
+ "bou.ke/monkey"
+ gomock "github.com/golang/mock/gomock"
+ "github.com/libp2p/go-libp2p-core/peer"
+ dht "github.com/libp2p/go-libp2p-kad-dht"
+ kb "github.com/libp2p/go-libp2p-kbucket"
+ ma "github.com/multiformats/go-multiaddr"
+ "github.com/rs/zerolog"
+ "github.com/stretchr/testify/assert"
+)
+
+// Crypto operations
+
+func TestEthereumCrypto(t *testing.T) {
+ //privateKey := "0xb60fe8027fb82f1a1bd6b8e66d4400f858989a2c67428a4e7f589441700339b0"
+ publicKey := "0xf753e5a9e2368e97f4db869a0d956d3ffb64672d6392670572906c786b5712ada13b6bff882951b3ba3dd65bdacc915c2b532efc3f183aa44657205c6c337225"
+ address := "0xb8d8c62d4a1999b7aea0aebBD5020244a4a9bAD8"
+ publicKeySignature := "0x304c2ba4ae7fa71295bfc2920b9c1268d574d65531f1f4d2117fc1439a45310c37ab75085a9df2a4169a4d47982b330a4387b1ded0c8881b030629db30bbaf3a1c"
+
+ addFromPublicKey, err := EthereumAddressFromPublicKey(publicKey)
+ if err != nil || addFromPublicKey != address {
+ t.Error(
+ "Error when computing address from public key or address and public key don't match",
+ )
+ }
+
+ _, err = BTCPubKeyFromEthereumPublicKey(publicKey)
+ if err != nil {
+ t.Errorf("While building BTC public key from string: %s", err.Error())
+ }
+
+ /*
+ ethSig, err := secp256k1.Sign(hashedPublicKey, hexutil.MustDecode(privateKey))
+ if err != nil {
+ t.Error(err.Error())
+ }
+ println(hexutil.Encode(ethSig))
+ hash := sha3.NewLegacyKeccak256()
+ _, err = hash.Write([]byte(publicKey))
+ if err != nil {
+ t.Error(err.Error())
+ }
+ sha3KeccakHash := hash.Sum(nil)
+ */
+
+ valid, err := VerifyEthereumSignatureETH([]byte(publicKey), publicKeySignature, publicKey)
+ if err != nil {
+ t.Error(err.Error())
+ }
+
+ if !valid {
+ t.Errorf("Signer address don't match %s", addFromPublicKey)
+ }
+}
+
+func TestFetchAICrypto(t *testing.T) {
+ publicKey := "02358e3e42a6ba15cf6b2ba6eb05f02b8893acf82b316d7dd9cda702b0892b8c71"
+ address := "fetch19dq2mkcpp6x0aypxt9c9gz6n4fqvax0x9a7t5r"
+ peerPublicKey := "027af21aff853b9d9589867ea142b0a60a9611fc8e1fae04c2f7144113fa4e938e"
+ pySigStrCanonize := "N/GOa7/m3HU8/gpLJ88VCQ6vXsdrfiiYcqnNtF+c2N9VG9ZIiycykN4hdbpbOCGrChMYZQA3G1GpozsShrUBgg=="
+
+ addressFromPublicKey, _ := FetchAIAddressFromPublicKey(publicKey)
+ if address != addressFromPublicKey {
+ t.Error("[ERR] Addresses don't match")
+ } else {
+ t.Log("[OK] Agent address matches its public key")
+ }
+
+ valid, err := VerifyFetchAISignatureBTC(
+ []byte(peerPublicKey),
+ pySigStrCanonize,
+ publicKey,
+ )
+ if !valid {
+ t.Errorf("Signature using BTC don't match %s", err.Error())
+ }
+ valid, err = VerifyFetchAISignatureLibp2p(
+ []byte(peerPublicKey),
+ pySigStrCanonize,
+ publicKey,
+ )
+ if !valid {
+ t.Errorf("Signature using LPP don't match %s", err.Error())
+ }
+}
+
+func TestSetLoggerLevel(t *testing.T) {
+ assert.Equal(t, logger.GetLevel(), zerolog.Level(0), "Initial log level is not 0")
+
+ lvl := zerolog.InfoLevel
+ SetLoggerLevel(lvl)
+
+ assert.Equal(
+ t,
+ logger.GetLevel(),
+ lvl,
+ "Waited for logger level %d but got %d",
+ lvl,
+ logger.GetLevel(),
+ )
+}
+
+func Example_ignore() {
+ ignore(errors.New("Test"))
+ // Output: IGNORED: Test
+}
+
+func TestNewDefaultLoggerWithFields(t *testing.T) {
+ fields := map[string]string{
+ "test_field": "test_value",
+ }
+ var logBuffer bytes.Buffer
+ logger := NewDefaultLoggerWithFields(fields).Output(&logBuffer)
+ logger.Info().Msg("test")
+ var jsonResult map[string]interface{}
+ err := json.Unmarshal(logBuffer.Bytes(), &jsonResult)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, jsonResult["test_field"], "test_value")
+}
+
+func TestComputeCID(t *testing.T) {
+ address := "fetch19dq2mkcpp6x0aypxt9c9gz6n4fqvax0x9a7t5r"
+ cid, err := ComputeCID(address)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, "QmZ6ryKyS9rSnesX8YnFLAmFwFuRMdHpE7pQ2V6SjXTbqM", cid.String())
+}
+
+func TestWriteBytes(t *testing.T) {
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ mockStream := mocks.NewMockStream(mockCtrl)
+ mockStream.EXPECT().Write([]byte{0, 0, 0, 5, 104, 101, 108, 108, 111}).Return(9, nil).Times(1)
+ err := WriteBytes(mockStream, []byte("hello"))
+ assert.Equal(t, nil, err)
+
+ mockStream.EXPECT().
+ Write([]byte{0, 0, 0, 4, 104, 101, 108, 108}).
+ Return(8, errors.New("oops")).
+ Times(1)
+ err = WriteBytes(mockStream, []byte("hell"))
+ assert.NotEqual(t, err, nil)
+}
+
+func TestReadBytesConn(t *testing.T) {
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ mockConn := mocks.NewMockConn(mockCtrl)
+ mockConn.EXPECT().Read(gomock.Any()).Return(4, nil).Times(2)
+ buf, err := ReadBytesConn(mockConn)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, "", string(buf))
+}
+
+func TestWriteBytesConn(t *testing.T) {
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ mockConn := mocks.NewMockConn(mockCtrl)
+ mockConn.EXPECT().Write(gomock.Any()).Return(0, nil).Times(1)
+ err := WriteBytesConn(mockConn, []byte("ABC"))
+ assert.Equal(t, nil, err)
+}
+
+func TestReadString(t *testing.T) {
+ // test ReadString and ReadBytes
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ mockStream := mocks.NewMockStream(mockCtrl)
+
+ defer monkey.UnpatchAll()
+
+ t.Run("TestReadString", func(t *testing.T) {
+ monkey.Patch(bufio.NewReader, func(reader io.Reader) *bufio.Reader {
+ return bufio.NewReaderSize(
+ bytes.NewReader([]byte{0, 0, 0, 5, 104, 101, 108, 108, 111}),
+ 100,
+ )
+ })
+ buf, err := ReadString(mockStream)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, "hello", buf)
+ })
+}
+
+func TestReadWriteEnvelope(t *testing.T) {
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ mockStream := mocks.NewMockStream(mockCtrl)
+ defer monkey.UnpatchAll()
+ address := "0xb8d8c62d4a1999b7aea0aebBD5020244a4a9bAD8"
+ buffer := bytes.NewBuffer([]byte{})
+
+ t.Run("TestWriteEnvelope", func(t *testing.T) {
+ monkey.Patch(bufio.NewWriter, func(writer io.Writer) *bufio.Writer {
+ return bufio.NewWriterSize(buffer, 100)
+ })
+ err := WriteEnvelope(&aea.Envelope{
+ To: address,
+ Sender: address,
+ }, mockStream)
+ assert.Equal(t, nil, err)
+ })
+
+ t.Run("TestReadEnvelope", func(t *testing.T) {
+ monkey.Patch(bufio.NewReader, func(reader io.Reader) *bufio.Reader {
+ return bufio.NewReaderSize(bytes.NewReader(buffer.Bytes()), 100)
+ })
+ env, err := ReadEnvelope(mockStream)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, address, env.To)
+ })
+}
+
+func TestReadWriteEnvelopeFromConnection(t *testing.T) {
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ defer monkey.UnpatchAll()
+ address := "0xb8d8c62d4a1999b7aea0aebBD5020244a4a9bAD8"
+ buffer := bytes.NewBuffer([]byte{})
+ mockConn := mocks.NewMockConn(mockCtrl)
+
+ t.Run("TestWriteEnvelope", func(t *testing.T) {
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(mockConn),
+ "Write",
+ func(_ *mocks.MockConn, b []byte) (int, error) {
+ buffer.Write(b)
+ return 0, nil
+ },
+ )
+
+ err := WriteEnvelopeConn(mockConn, &aea.Envelope{
+ To: address,
+ Sender: address,
+ })
+ assert.Equal(t, nil, err)
+ assert.NotEqual(t, 0, buffer)
+ })
+
+ t.Run("TestReadEnvelope", func(t *testing.T) {
+ monkey.Patch(ReadBytesConn, func(conn net.Conn) ([]byte, error) {
+ return buffer.Bytes()[4:], nil
+ })
+ env, err := ReadEnvelopeConn(mockConn)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, address, env.To)
+ })
+}
+
+func TestGetPeersAddrInfo(t *testing.T) {
+ addrs, err := GetPeersAddrInfo(
+ []string{
+ "/dns4/acn.fetch.ai/tcp/9001/p2p/16Uiu2HAmVWnopQAqq4pniYLw44VRvYxBUoRHqjz1Hh2SoCyjbyRW",
+ },
+ )
+ assert.Equal(t, nil, err)
+ assert.Equal(t, 1, len(addrs))
+}
+
+func TestFetchAIPublicKeyFromPubKey(t *testing.T) {
+ //(publicKey crypto.PubKey) (string, error) {
+ _, pubKey, err := KeyPairFromFetchAIKey(
+ "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc",
+ )
+ assert.Equal(t, nil, err)
+ key, err := FetchAIPublicKeyFromPubKey(pubKey)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, "03b7e977f498dce004e2614764ff576e17cc6691135497e7bcb5d3441e816ba9e1", key)
+}
+
+func TestIDFromFetchAIPublicKey(t *testing.T) {
+ _, pubKey, err := KeyPairFromFetchAIKey(
+ "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc",
+ )
+ assert.Equal(t, nil, err)
+ key, err := FetchAIPublicKeyFromPubKey(pubKey)
+ assert.Equal(t, nil, err)
+ peerID, err := IDFromFetchAIPublicKey(key)
+ assert.Equal(t, nil, err)
+ assert.NotEqual(t, 0, len(peerID))
+}
+
+func TestAgentAddressFromPublicKey(t *testing.T) {
+ address, err := AgentAddressFromPublicKey(
+ "fetchai",
+ "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc",
+ )
+ assert.Equal(t, nil, err)
+ assert.NotEqual(t, 0, len(address))
+}
+
+func TestCosmosAddressFromPublicKey(t *testing.T) {
+ address, err := CosmosAddressFromPublicKey(
+ "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc",
+ )
+ assert.Equal(t, nil, err)
+ assert.NotEqual(t, 0, len(address))
+}
+
+func TestFetchAIPublicKeyFromFetchAIPrivateKey(t *testing.T) {
+ key, err := FetchAIPublicKeyFromFetchAIPrivateKey(
+ "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc",
+ )
+ assert.Equal(t, nil, err)
+ assert.Equal(t, "03b7e977f498dce004e2614764ff576e17cc6691135497e7bcb5d3441e816ba9e1", key)
+}
+
+func TestIDFromFetchAIPublicKeyUncompressed(t *testing.T) {
+ //bad pub key
+ _, err := IDFromFetchAIPublicKeyUncompressed("some")
+ assert.NotEqual(t, nil, err)
+ // good pub key
+ id, err := IDFromFetchAIPublicKeyUncompressed(
+ "50863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6",
+ )
+ assert.Equal(t, nil, err)
+ assert.Equal(
+ t,
+ peer.ID(
+ "\x00%\b\x02\x12!\x02P\x86:\xd6J\x87\xae\x8a/\xe8<\x1a\xf1\xa8@<\xb5?S\xe4\x86\xd8Q\x1d\xad\x8a\x04\x88~[#R",
+ ),
+ id,
+ )
+}
+
+func TestSignFetchAI(t *testing.T) {
+ privKey := "3e7a1f43b2d8a4b9f63a2ffeb1d597f971a8db7ffd95453173268b453106cadc"
+ message := []byte("somebytes")
+
+ _, pubKey, err := KeyPairFromFetchAIKey(privKey)
+ assert.Equal(t, nil, err)
+ fetchPubKey, err := FetchAIPublicKeyFromPubKey(pubKey)
+ assert.Equal(t, nil, err)
+
+ signature, err := SignFetchAI(message, privKey)
+ assert.Equal(t, nil, err)
+ assert.NotEqual(t, 0, len(signature))
+
+ isValid, err := VerifyLedgerSignature("fetchai", message, signature, fetchPubKey)
+ assert.Equal(t, nil, err)
+ assert.Equal(t, true, isValid)
+
+}
+
+func TestBootstrapConnect(t *testing.T) {
+ ctx := context.Background()
+ mockCtrl := gomock.NewController(t)
+ defer mockCtrl.Finish()
+ defer monkey.UnpatchAll()
+ var ipfsdht *dht.IpfsDHT
+ var routingTable *kb.RoutingTable
+
+ mockPeerstore := mocks.NewMockPeerstore(mockCtrl)
+ peers := make([]peer.AddrInfo, 2)
+ var addrs []ma.Multiaddr
+ peers[0] = peer.AddrInfo{ID: peer.ID("peer1"), Addrs: addrs}
+ peers[1] = peer.AddrInfo{ID: peer.ID("peer2"), Addrs: addrs}
+
+ mockHost := mocks.NewMockHost(mockCtrl)
+
+ mockHost.EXPECT().ID().Return(peer.ID("host_id")).Times(2)
+ mockHost.EXPECT().Peerstore().Return(mockPeerstore).Times(2)
+ mockHost.EXPECT().Connect(gomock.Any(), gomock.Any()).Return(nil).Times(2)
+ mockPeerstore.EXPECT().AddAddrs(gomock.Any(), gomock.Any(), gomock.Any()).Return().Times(2)
+
+ t.Run("TestOk", func(t *testing.T) {
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(routingTable),
+ "Find",
+ func(_ *kb.RoutingTable, _ peer.ID) peer.ID {
+ return peer.ID("som peer")
+ },
+ )
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(ipfsdht),
+ "RoutingTable",
+ func(_ *dht.IpfsDHT) *kb.RoutingTable {
+ return routingTable
+ },
+ )
+
+ err := BootstrapConnect(ctx, mockHost, ipfsdht, peers)
+ assert.Equal(t, nil, err)
+ })
+
+ mockHost = mocks.NewMockHost(mockCtrl)
+
+ mockHost.EXPECT().ID().Return(peer.ID("host_id")).Times(2)
+ mockHost.EXPECT().Peerstore().Return(mockPeerstore).Times(2)
+ mockHost.EXPECT().Connect(gomock.Any(), gomock.Any()).Return(nil).Times(2)
+ mockPeerstore.EXPECT().AddAddrs(gomock.Any(), gomock.Any(), gomock.Any()).Return().Times(2)
+
+ t.Run("Test_PeersNotAdded", func(t *testing.T) {
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(routingTable),
+ "Find",
+ func(_ *kb.RoutingTable, _ peer.ID) peer.ID {
+ return peer.ID("")
+ },
+ )
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(ipfsdht),
+ "RoutingTable",
+ func(_ *dht.IpfsDHT) *kb.RoutingTable {
+ return routingTable
+ },
+ )
+
+ err := BootstrapConnect(ctx, mockHost, ipfsdht, peers)
+ assert.NotEqual(t, nil, err)
+ assert.Contains(t, err.Error(), "timeout: entry peer haven't been added to DHT")
+ })
+
+ mockHost = mocks.NewMockHost(mockCtrl)
+
+ mockHost.EXPECT().ID().Return(peer.ID("host_id")).Times(2)
+ mockHost.EXPECT().Peerstore().Return(mockPeerstore).Times(2)
+ mockHost.EXPECT().Connect(gomock.Any(), gomock.Any()).Return(errors.New("some error")).Times(2)
+ mockPeerstore.EXPECT().AddAddrs(gomock.Any(), gomock.Any(), gomock.Any()).Return().Times(2)
+
+ t.Run("Test_PeersNotConnected", func(t *testing.T) {
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(routingTable),
+ "Find",
+ func(_ *kb.RoutingTable, _ peer.ID) peer.ID {
+ return peer.ID("")
+ },
+ )
+ monkey.PatchInstanceMethod(
+ reflect.TypeOf(ipfsdht),
+ "RoutingTable",
+ func(_ *dht.IpfsDHT) *kb.RoutingTable {
+ return routingTable
+ },
+ )
+
+ err := BootstrapConnect(ctx, mockHost, ipfsdht, peers)
+ assert.NotEqual(t, nil, err)
+ assert.Equal(t, "failed to bootstrap: some error", err.Error())
+ })
+
+}
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 84274a556f..0c64dda7ef 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmQ1FBNQezRPufMZDyVcW4KuADyKPQHb2Xo4qtLFcTgmAD
+fetchai/connections/p2p_libp2p,QmTw3hmsvSggmWkEnh74VbGMn4CZKRES1c2FEE6jroGyfD
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
From 1e81944743a6f7593a72f9369028553d18e09348 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 10 May 2021 22:04:06 +0200
Subject: [PATCH 030/147] parametrize bumper version helper class
---
scripts/bump_aea_version.py | 191 +++++++++++++++++++++++-------------
1 file changed, 124 insertions(+), 67 deletions(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index 9f2a1d0cdd..0d6660bdf0 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -27,8 +27,9 @@
import sys
from functools import wraps
from pathlib import Path
-from typing import Optional
+from typing import Any, Callable, Collection, Optional, Pattern, Tuple, cast
+from packaging.specifiers import SpecifierSet
from packaging.version import Version
from aea.configurations.constants import (
@@ -62,14 +63,27 @@
)
)
-IGNORE_DIRS = [Path(".git")]
-
-
-def check_executed(func):
+_AEA_ALL_PATTERN = "(?<={package_name}\[all\]==){version}"
+AEA_PATHS = [
+ (Path("deploy-image", "Dockerfile"), _AEA_ALL_PATTERN),
+ (Path("develop-image", "docker-env.sh"), "(?<=aea-develop:){version}"),
+ (Path("docs", "quickstart.md"), "(?<=v){version}"),
+ (Path("examples", "tac_deploy", "Dockerfile"), _AEA_ALL_PATTERN),
+ (Path("scripts", "install.ps1"), _AEA_ALL_PATTERN),
+ (Path("scripts", "install.sh"), _AEA_ALL_PATTERN),
+ (
+ Path("tests", "test_docs", "test_bash_yaml", "md_files", "bash-quickstart.md"),
+ "(?<=v){version}",
+ ),
+ (Path("user-image", "docker-env.sh"), "(?<=aea-user:){version}"),
+]
+
+
+def check_executed(func: Callable) -> Callable:
"""Check a functor has been already executed; if yes, raise error."""
@wraps(func)
- def wrapper(self, *args, **kwargs):
+ def wrapper(self: Any, *args: Any, **kwargs: Any) -> None:
if self.is_executed:
raise ValueError("already executed")
self._executed = True
@@ -81,19 +95,35 @@ def wrapper(self, *args, **kwargs):
class PythonPackageVersionBumper:
"""Utility class to bump Python package versions."""
- def __init__(self, root_dir: Path, python_pkg_dir: Path, new_version: Version):
+ IGNORE_DIRS = (Path(".git"),)
+
+ def __init__(
+ self,
+ root_dir: Path,
+ python_pkg_dir: Path,
+ new_version: Version,
+ package_name: Optional[str] = None,
+ files_to_pattern: Collection[Tuple[Path, str]] = (),
+ ignore_dirs: Collection[Path] = (),
+ ):
"""
Initialize the utility class.
:param root_dir: the root directory from which to look for files.
:param python_pkg_dir: the path to the Python package to upgrade.
:param new_version: the new version.
+ :param package_name: the Python package name aliases (defaults to
+ dirname of python_pkg_dir).
+ :param ignore_dirs: a list of paths to ignore during the substitution.
"""
self.root_dir = root_dir
self.python_pkg_dir = python_pkg_dir
self.new_version = new_version
+ self.package_name = package_name or self.python_pkg_dir.name
+ self.ignore_dirs = ignore_dirs or self.IGNORE_DIRS
+ self.files_to_pattern = files_to_pattern
- self._current_version = None
+ self._current_version: Optional[str] = None
# functor pattern
self._executed: bool = False
@@ -113,13 +143,13 @@ def result(self) -> bool:
"""Get the result."""
if not self.is_executed:
raise ValueError("not executed yet")
- return self._result
+ return cast(bool, self._result)
@check_executed
def run(self) -> bool:
"""Main entrypoint."""
new_version_string = str(self.new_version)
- current_version_str = self.update_version_for_aea(new_version_string)
+ current_version_str = self.update_version_for_package(new_version_string)
# validate current version
current_version: Version = Version(current_version_str)
@@ -127,29 +157,19 @@ def run(self) -> bool:
self._current_version = current_version_str
self.update_version_for_files()
- return update_aea_version_specifiers(current_version, self.new_version)
+ return self.update_version_specifiers(current_version, self.new_version)
def update_version_for_files(self) -> None:
"""Update the version."""
- files = [
- Path("benchmark", "run_from_branch.sh"),
- Path("deploy-image", "Dockerfile"),
- Path("develop-image", "docker-env.sh"),
- Path("docs", "quickstart.md"),
- Path("examples", "tac_deploy", "Dockerfile"),
- Path("scripts", "install.ps1"),
- Path("scripts", "install.sh"),
- Path(
- "tests", "test_docs", "test_bash_yaml", "md_files", "bash-quickstart.md"
- ),
- Path("user-image", "docker-env.sh"),
- ]
- for filepath in files:
+ for filepath, regex_template in self.files_to_pattern:
self.update_version_for_file(
- filepath, self._current_version, str(self.new_version)
+ filepath,
+ cast(str, self._current_version),
+ str(self.new_version),
+ version_regex_template=regex_template,
)
- def update_version_for_aea(self, new_version: str) -> str:
+ def update_version_for_package(self, new_version: str) -> str:
"""
Update version for file.
@@ -157,7 +177,7 @@ def update_version_for_aea(self, new_version: str) -> str:
:return: the current version
"""
current_version = ""
- path = Path("aea", "__version__.py")
+ path = self.python_pkg_dir / Path("__version__.py")
with open(path, "rt") as fin:
for line in fin:
if "__version__" not in line:
@@ -171,56 +191,93 @@ def update_version_for_aea(self, new_version: str) -> str:
self.update_version_for_file(path, current_version, new_version)
return current_version
- @classmethod
def update_version_for_file(
- cls, path: Path, current_version: str, new_version: str
+ self,
+ path: Path,
+ current_version: str,
+ new_version: str,
+ version_regex_template: Optional[str] = None,
) -> None:
"""
Update version for file.
:param path: the file path
- :param current_version: the current version
+ :param current_version: the regex for the current version
:param new_version: the new version
+ :param version_regex_template: the regex template
+ to replace with the current version. Defaults to exactly
+ the current version.
"""
+ if version_regex_template is not None:
+ regex_str = version_regex_template.format(package_name=self.package_name, version=current_version)
+ else:
+ regex_str = current_version
+ pattern = re.compile(regex_str)
content = path.read_text()
- content = content.replace(current_version, new_version)
+ content = pattern.sub(new_version, content)
path.write_text(content)
+ def update_version_specifiers(
+ self, old_version: Version, new_version: Version
+ ) -> bool:
+ """
+ Update specifier set.
-def update_aea_version_specifiers(old_version: Version, new_version: Version) -> bool:
- """
- Update aea_version specifier set in docs.
-
- :param old_version: the old version.
- :param new_version: the new version.
- :return: True if the update has been done, False otherwise.
- """
- old_specifier_set = compute_specifier_from_version(old_version)
- new_specifier_set = compute_specifier_from_version(new_version)
- print(f"Old version specifier: {old_specifier_set}")
- print(f"New version specifier: {new_specifier_set}")
- old_specifier_set_regex = re.compile(str(old_specifier_set).replace(" ", " *"))
- if old_specifier_set == new_specifier_set:
- print("Not updating version specifier - they haven't changed.")
- return False
- for file in filter(lambda p: not p.is_dir(), Path(".").rglob("*")):
- dir_root = Path(file.parts[0])
- if dir_root in IGNORE_DIRS:
- print(f"Skipping '{file}'...")
- continue
- print(
- f"Replacing '{old_specifier_set}' with '{new_specifier_set}' in '{file}'... ",
- end="",
- )
- try:
- content = file.read_text()
- except UnicodeDecodeError as e:
- print(f"Cannot read {file}: {str(e)}. Continue...")
- else:
- if old_specifier_set_regex.search(content) is not None:
- content = old_specifier_set_regex.sub(new_specifier_set, content)
- file.write_text(content)
- return True
+ :param old_version: the old version.
+ :param new_version: the new version.
+ :return: True if the update has been done, False otherwise.
+ """
+ old_specifier_set = compute_specifier_from_version(old_version)
+ new_specifier_set = compute_specifier_from_version(new_version)
+ print(f"Old version specifier: {old_specifier_set}")
+ print(f"New version specifier: {new_specifier_set}")
+ old_specifier_set_regex = self.get_regex_from_specifier_set(old_specifier_set)
+ if old_specifier_set == new_specifier_set:
+ print("Not updating version specifier - they haven't changed.")
+ return False
+ for file in filter(lambda p: not p.is_dir(), self.root_dir.rglob("*")):
+ dir_root = Path(file.parts[0])
+ if dir_root in self.ignore_dirs:
+ print(f"Skipping '{file}'...")
+ continue
+ print(
+ f"Replacing '{old_specifier_set}' with '{new_specifier_set}' in '{file}'... ",
+ end="",
+ )
+ try:
+ content = file.read_text()
+ except UnicodeDecodeError as e:
+ print(f"Cannot read {file}: {str(e)}. Continue...")
+ else:
+ if old_specifier_set_regex.search(content) is not None:
+ content = old_specifier_set_regex.sub(new_specifier_set, content)
+ file.write_text(content)
+ return True
+
+ def get_regex_from_specifier_set(self, specifier_set: str) -> Pattern:
+ """
+ Get the regex for specifier sets.
+
+ This function accepts input of the form:
+
+ ">={lower_bound_version}, <{upper_bound_version}"
+
+ And computes a regex pattern:
+
+ ">={lower_bound_version}, *<{upper_bound_version}|<{upper_bound_version}, *>={lower_bound_version}"
+
+ i.e. not considering the order of the specifiers.
+
+ :param specifier_set: The string representation of the specifier set
+ :return: a regex pattern
+ """
+ # TODO add different type of matches
+ specifiers = SpecifierSet(specifier_set)
+ upper, lower = sorted(specifiers, key=lambda x: str(x))
+ alternatives = list()
+ alternatives.append(f"{upper} *{lower}")
+ alternatives.append(f"{lower} *{upper}")
+ return re.compile("|".join(alternatives))
def parse_args() -> argparse.Namespace:
@@ -240,7 +297,7 @@ def parse_args() -> argparse.Namespace:
new_aea_version = Version(arguments.new_version)
aea_version_bumper = PythonPackageVersionBumper(
- AEA_DIR.parent, AEA_DIR, new_aea_version
+ AEA_DIR.parent, AEA_DIR, new_aea_version, files_to_pattern=AEA_PATHS
)
have_updated_specifier_set = aea_version_bumper.run()
From e1c7ec3805093c1c5d3db8da47d64642cefaa379 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 00:18:34 +0200
Subject: [PATCH 031/147] update bump script so to add flexible specifier
update
---
scripts/bump_aea_version.py | 84 ++++++++++++++++++++++++-------------
1 file changed, 56 insertions(+), 28 deletions(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index 0d6660bdf0..773d8ea8ae 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -27,7 +27,7 @@
import sys
from functools import wraps
from pathlib import Path
-from typing import Any, Callable, Collection, Optional, Pattern, Tuple, cast
+from typing import Any, Callable, Collection, Dict, Optional, cast
from packaging.specifiers import SpecifierSet
from packaging.version import Version
@@ -63,20 +63,19 @@
)
)
-_AEA_ALL_PATTERN = "(?<={package_name}\[all\]==){version}"
-AEA_PATHS = [
- (Path("deploy-image", "Dockerfile"), _AEA_ALL_PATTERN),
- (Path("develop-image", "docker-env.sh"), "(?<=aea-develop:){version}"),
- (Path("docs", "quickstart.md"), "(?<=v){version}"),
- (Path("examples", "tac_deploy", "Dockerfile"), _AEA_ALL_PATTERN),
- (Path("scripts", "install.ps1"), _AEA_ALL_PATTERN),
- (Path("scripts", "install.sh"), _AEA_ALL_PATTERN),
- (
- Path("tests", "test_docs", "test_bash_yaml", "md_files", "bash-quickstart.md"),
- "(?<=v){version}",
- ),
- (Path("user-image", "docker-env.sh"), "(?<=aea-user:){version}"),
-]
+_AEA_ALL_PATTERN = r"(?<={package_name}\[all\]==){version}"
+AEA_PATHS = {
+ Path("deploy-image", "Dockerfile"): _AEA_ALL_PATTERN,
+ Path("develop-image", "docker-env.sh"): "(?<=aea-develop:){version}",
+ Path("docs", "quickstart.md"): "(?<=v){version}",
+ Path("examples", "tac_deploy", "Dockerfile"): _AEA_ALL_PATTERN,
+ Path("scripts", "install.ps1"): _AEA_ALL_PATTERN,
+ Path("scripts", "install.sh"): _AEA_ALL_PATTERN,
+ Path(
+ "tests", "test_docs", "test_bash_yaml", "md_files", "bash-quickstart.md"
+ ): "(?<=v){version}",
+ Path("user-image", "docker-env.sh"): "(?<=aea-user:){version}",
+}
def check_executed(func: Callable) -> Callable:
@@ -95,15 +94,18 @@ def wrapper(self: Any, *args: Any, **kwargs: Any) -> None:
class PythonPackageVersionBumper:
"""Utility class to bump Python package versions."""
- IGNORE_DIRS = (Path(".git"),)
+ IGNORE_DIRS = (
+ Path(".git"),
+ )
def __init__(
self,
root_dir: Path,
python_pkg_dir: Path,
new_version: Version,
+ files_to_pattern: Dict[Path, str],
+ specifier_set_patterns: Collection[str],
package_name: Optional[str] = None,
- files_to_pattern: Collection[Tuple[Path, str]] = (),
ignore_dirs: Collection[Path] = (),
):
"""
@@ -114,14 +116,17 @@ def __init__(
:param new_version: the new version.
:param package_name: the Python package name aliases (defaults to
dirname of python_pkg_dir).
+ :param files_to_pattern: a list of pairs.
+ :param specifier_set_patterns: a list of patterns for specifier sets.
:param ignore_dirs: a list of paths to ignore during the substitution.
"""
self.root_dir = root_dir
self.python_pkg_dir = python_pkg_dir
self.new_version = new_version
+ self.files_to_pattern = files_to_pattern
+ self.specifier_set_patterns = specifier_set_patterns
self.package_name = package_name or self.python_pkg_dir.name
self.ignore_dirs = ignore_dirs or self.IGNORE_DIRS
- self.files_to_pattern = files_to_pattern
self._current_version: Optional[str] = None
@@ -161,7 +166,7 @@ def run(self) -> bool:
def update_version_for_files(self) -> None:
"""Update the version."""
- for filepath, regex_template in self.files_to_pattern:
+ for filepath, regex_template in self.files_to_pattern.items():
self.update_version_for_file(
filepath,
cast(str, self._current_version),
@@ -209,7 +214,9 @@ def update_version_for_file(
the current version.
"""
if version_regex_template is not None:
- regex_str = version_regex_template.format(package_name=self.package_name, version=current_version)
+ regex_str = version_regex_template.format(
+ package_name=self.package_name, version=current_version
+ )
else:
regex_str = current_version
pattern = re.compile(regex_str)
@@ -231,7 +238,6 @@ def update_version_specifiers(
new_specifier_set = compute_specifier_from_version(new_version)
print(f"Old version specifier: {old_specifier_set}")
print(f"New version specifier: {new_specifier_set}")
- old_specifier_set_regex = self.get_regex_from_specifier_set(old_specifier_set)
if old_specifier_set == new_specifier_set:
print("Not updating version specifier - they haven't changed.")
return False
@@ -249,12 +255,28 @@ def update_version_specifiers(
except UnicodeDecodeError as e:
print(f"Cannot read {file}: {str(e)}. Continue...")
else:
- if old_specifier_set_regex.search(content) is not None:
- content = old_specifier_set_regex.sub(new_specifier_set, content)
- file.write_text(content)
+ content = self._replace_specifier_sets(
+ old_specifier_set, new_specifier_set, content
+ )
+ file.write_text(content)
return True
- def get_regex_from_specifier_set(self, specifier_set: str) -> Pattern:
+ def _replace_specifier_sets(
+ self, old_specifier_set: str, new_specifier_set: str, content: str
+ ) -> str:
+ old_specifier_set_regex = self.get_regex_from_specifier_set(old_specifier_set)
+ for pattern_template in self.specifier_set_patterns:
+ pattern = re.compile(
+ pattern_template.format(
+ package_name=self.package_name,
+ specifier_set=old_specifier_set_regex,
+ )
+ )
+ if pattern.search(content) is not None:
+ content = pattern.sub(new_specifier_set, content)
+ return content
+
+ def get_regex_from_specifier_set(self, specifier_set: str) -> str:
"""
Get the regex for specifier sets.
@@ -271,13 +293,12 @@ def get_regex_from_specifier_set(self, specifier_set: str) -> Pattern:
:param specifier_set: The string representation of the specifier set
:return: a regex pattern
"""
- # TODO add different type of matches
specifiers = SpecifierSet(specifier_set)
upper, lower = sorted(specifiers, key=lambda x: str(x))
alternatives = list()
alternatives.append(f"{upper} *{lower}")
alternatives.append(f"{lower} *{upper}")
- return re.compile("|".join(alternatives))
+ return "|".join(alternatives)
def parse_args() -> argparse.Namespace:
@@ -297,7 +318,14 @@ def parse_args() -> argparse.Namespace:
new_aea_version = Version(arguments.new_version)
aea_version_bumper = PythonPackageVersionBumper(
- AEA_DIR.parent, AEA_DIR, new_aea_version, files_to_pattern=AEA_PATHS
+ AEA_DIR.parent,
+ AEA_DIR,
+ new_aea_version,
+ specifier_set_patterns=[
+ "(?<=aea_version:) *({specifier_set})",
+ "(?<={package_name})({specifier_set})",
+ ],
+ files_to_pattern=AEA_PATHS,
)
have_updated_specifier_set = aea_version_bumper.run()
From e903e544ea7025e666af2522a59b05c0216fca85 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Tue, 11 May 2021 11:36:06 +0300
Subject: [PATCH 032/147] libp2p utils fixes/typos/cleanup
---
libs/go/libp2p_node/utils/utils.go | 76 ++-----------------
libs/go/libp2p_node/utils/utils_test.go | 52 -------------
.../connections/p2p_libp2p/connection.yaml | 4 +-
.../p2p_libp2p/libp2p_node/utils/utils.go | 76 ++-----------------
.../libp2p_node/utils/utils_test.go | 52 -------------
packages/hashes.csv | 2 +-
6 files changed, 13 insertions(+), 249 deletions(-)
diff --git a/libs/go/libp2p_node/utils/utils.go b/libs/go/libp2p_node/utils/utils.go
index c8b533be0e..728d9a123e 100644
--- a/libs/go/libp2p_node/utils/utils.go
+++ b/libs/go/libp2p_node/utils/utils.go
@@ -420,8 +420,8 @@ func RecoverAddressFromEthereumSignature(message []byte, signature string) (stri
// VerifyEthereumSignatureETH verify ethereum signature using ethereum public key
func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string) (bool, error) {
- // get ted signer address
- tedAddress, err := EthereumAddressFromPublicKey(pubkey)
+ // get expected signer address
+ expectedAddress, err := EthereumAddressFromPublicKey(pubkey)
if err != nil {
return false, err
}
@@ -432,8 +432,8 @@ func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string)
return false, err
}
- if recoveredAddress != tedAddress {
- return false, errors.New("recovered and ted addresses don't match")
+ if recoveredAddress != expectedAddress {
+ return false, errors.New("recovered and expected addresses don't match")
}
return true, nil
@@ -743,70 +743,4 @@ func WriteBytes(s network.Stream, data []byte) error {
err = wstream.Flush()
return err
-}
-
-// ReadString from a network stream
-func ReadString(s network.Stream) (string, error) {
- data, err := ReadBytes(s)
- return string(data), err
-}
-
-// WriteEnvelope to a network stream
-func WriteEnvelope(envel *aea.Envelope, s network.Stream) error {
- wstream := bufio.NewWriter(s)
- data, err := proto.Marshal(envel)
- if err != nil {
- return err
- }
- size := uint32(len(data))
-
- buf := make([]byte, 4)
- binary.BigEndian.PutUint32(buf, size)
- //log.Println("DEBUG writing size:", size, buf)
- _, err = wstream.Write(buf)
- if err != nil {
- return err
- }
-
- //log.Println("DEBUG writing data:", data)
- _, err = wstream.Write(data)
- if err != nil {
- return err
- }
-
- wstream.Flush()
- return nil
-}
-
-// ReadEnvelope from a network stream
-func ReadEnvelope(s network.Stream) (*aea.Envelope, error) {
- envel := &aea.Envelope{}
- rstream := bufio.NewReader(s)
-
- buf := make([]byte, 4)
- _, err := io.ReadFull(rstream, buf)
-
- if err != nil {
- logger.Error().
- Str("err", err.Error()).
- Msg("while reading size")
- return envel, err
- }
-
- size := binary.BigEndian.Uint32(buf)
- if size > maxMessageSizeDelegateConnection {
- return nil, errors.New("ted message size larger than maximum allowed")
- }
- //logger.Debug().Msgf("received size: %d %x", size, buf)
- buf = make([]byte, size)
- _, err = io.ReadFull(rstream, buf)
- if err != nil {
- logger.Error().
- Str("err", err.Error()).
- Msg("while reading data")
- return envel, err
- }
-
- err = proto.Unmarshal(buf, envel)
- return envel, err
-}
+}
\ No newline at end of file
diff --git a/libs/go/libp2p_node/utils/utils_test.go b/libs/go/libp2p_node/utils/utils_test.go
index f959b0cabd..237a787054 100644
--- a/libs/go/libp2p_node/utils/utils_test.go
+++ b/libs/go/libp2p_node/utils/utils_test.go
@@ -21,12 +21,10 @@
package utils
import (
- "bufio"
"bytes"
"context"
"encoding/json"
"errors"
- "io"
"libp2p_node/aea"
mocks "libp2p_node/mocks"
"net"
@@ -194,56 +192,6 @@ func TestWriteBytesConn(t *testing.T) {
assert.Equal(t, nil, err)
}
-func TestReadString(t *testing.T) {
- // test ReadString and ReadBytes
- mockCtrl := gomock.NewController(t)
- defer mockCtrl.Finish()
- mockStream := mocks.NewMockStream(mockCtrl)
-
- defer monkey.UnpatchAll()
-
- t.Run("TestReadString", func(t *testing.T) {
- monkey.Patch(bufio.NewReader, func(reader io.Reader) *bufio.Reader {
- return bufio.NewReaderSize(
- bytes.NewReader([]byte{0, 0, 0, 5, 104, 101, 108, 108, 111}),
- 100,
- )
- })
- buf, err := ReadString(mockStream)
- assert.Equal(t, nil, err)
- assert.Equal(t, "hello", buf)
- })
-}
-
-func TestReadWriteEnvelope(t *testing.T) {
- mockCtrl := gomock.NewController(t)
- defer mockCtrl.Finish()
- mockStream := mocks.NewMockStream(mockCtrl)
- defer monkey.UnpatchAll()
- address := "0xb8d8c62d4a1999b7aea0aebBD5020244a4a9bAD8"
- buffer := bytes.NewBuffer([]byte{})
-
- t.Run("TestWriteEnvelope", func(t *testing.T) {
- monkey.Patch(bufio.NewWriter, func(writer io.Writer) *bufio.Writer {
- return bufio.NewWriterSize(buffer, 100)
- })
- err := WriteEnvelope(&aea.Envelope{
- To: address,
- Sender: address,
- }, mockStream)
- assert.Equal(t, nil, err)
- })
-
- t.Run("TestReadEnvelope", func(t *testing.T) {
- monkey.Patch(bufio.NewReader, func(reader io.Reader) *bufio.Reader {
- return bufio.NewReaderSize(bytes.NewReader(buffer.Bytes()), 100)
- })
- env, err := ReadEnvelope(mockStream)
- assert.Equal(t, nil, err)
- assert.Equal(t, address, env.To)
- })
-}
-
func TestReadWriteEnvelopeFromConnection(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index 448470fcab..950b1237ca 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -41,8 +41,8 @@ fingerprint:
libp2p_node/mocks/mock_net.go: QmVKnkDdH8XCJ9jriEkZui4NoB36GBYF2DtfX8uCqAthMw
libp2p_node/mocks/mock_network.go: QmbVVvd3wrY6PnVs1rn9T9m6FD5kbmSVJLwhSxUgSLAiM5
libp2p_node/mocks/mock_peerstore.go: QmaPCBrwsTeWCHZoAKDzaxN6uhY3bez1karzeGeovWYwkB
- libp2p_node/utils/utils.go: QmXxQCCsEFZH1wkzze1Z1MfcBi6rQ7ZEzACGKptQsgL8Zg
- libp2p_node/utils/utils_test.go: QmX5bBqCwFVky6ix7pu9QNvScntr3GMDvon9cNC8dKhJiS
+ libp2p_node/utils/utils.go: QmW8ri6vw6CwyJXYHUMhYWoH8RwuMBnbryf5fb6YzE8Fik
+ libp2p_node/utils/utils_test.go: QmaUTrtqhPYcCLTHnJic4EN7R1pZY8ra7QbeRrPuedgAuc
fingerprint_ignore_patterns: []
build_entrypoint: check_dependencies.py
connections: []
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
index c8b533be0e..728d9a123e 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
@@ -420,8 +420,8 @@ func RecoverAddressFromEthereumSignature(message []byte, signature string) (stri
// VerifyEthereumSignatureETH verify ethereum signature using ethereum public key
func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string) (bool, error) {
- // get ted signer address
- tedAddress, err := EthereumAddressFromPublicKey(pubkey)
+ // get expected signer address
+ expectedAddress, err := EthereumAddressFromPublicKey(pubkey)
if err != nil {
return false, err
}
@@ -432,8 +432,8 @@ func VerifyEthereumSignatureETH(message []byte, signature string, pubkey string)
return false, err
}
- if recoveredAddress != tedAddress {
- return false, errors.New("recovered and ted addresses don't match")
+ if recoveredAddress != expectedAddress {
+ return false, errors.New("recovered and expected addresses don't match")
}
return true, nil
@@ -743,70 +743,4 @@ func WriteBytes(s network.Stream, data []byte) error {
err = wstream.Flush()
return err
-}
-
-// ReadString from a network stream
-func ReadString(s network.Stream) (string, error) {
- data, err := ReadBytes(s)
- return string(data), err
-}
-
-// WriteEnvelope to a network stream
-func WriteEnvelope(envel *aea.Envelope, s network.Stream) error {
- wstream := bufio.NewWriter(s)
- data, err := proto.Marshal(envel)
- if err != nil {
- return err
- }
- size := uint32(len(data))
-
- buf := make([]byte, 4)
- binary.BigEndian.PutUint32(buf, size)
- //log.Println("DEBUG writing size:", size, buf)
- _, err = wstream.Write(buf)
- if err != nil {
- return err
- }
-
- //log.Println("DEBUG writing data:", data)
- _, err = wstream.Write(data)
- if err != nil {
- return err
- }
-
- wstream.Flush()
- return nil
-}
-
-// ReadEnvelope from a network stream
-func ReadEnvelope(s network.Stream) (*aea.Envelope, error) {
- envel := &aea.Envelope{}
- rstream := bufio.NewReader(s)
-
- buf := make([]byte, 4)
- _, err := io.ReadFull(rstream, buf)
-
- if err != nil {
- logger.Error().
- Str("err", err.Error()).
- Msg("while reading size")
- return envel, err
- }
-
- size := binary.BigEndian.Uint32(buf)
- if size > maxMessageSizeDelegateConnection {
- return nil, errors.New("ted message size larger than maximum allowed")
- }
- //logger.Debug().Msgf("received size: %d %x", size, buf)
- buf = make([]byte, size)
- _, err = io.ReadFull(rstream, buf)
- if err != nil {
- logger.Error().
- Str("err", err.Error()).
- Msg("while reading data")
- return envel, err
- }
-
- err = proto.Unmarshal(buf, envel)
- return envel, err
-}
+}
\ No newline at end of file
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils_test.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils_test.go
index f959b0cabd..237a787054 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils_test.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils_test.go
@@ -21,12 +21,10 @@
package utils
import (
- "bufio"
"bytes"
"context"
"encoding/json"
"errors"
- "io"
"libp2p_node/aea"
mocks "libp2p_node/mocks"
"net"
@@ -194,56 +192,6 @@ func TestWriteBytesConn(t *testing.T) {
assert.Equal(t, nil, err)
}
-func TestReadString(t *testing.T) {
- // test ReadString and ReadBytes
- mockCtrl := gomock.NewController(t)
- defer mockCtrl.Finish()
- mockStream := mocks.NewMockStream(mockCtrl)
-
- defer monkey.UnpatchAll()
-
- t.Run("TestReadString", func(t *testing.T) {
- monkey.Patch(bufio.NewReader, func(reader io.Reader) *bufio.Reader {
- return bufio.NewReaderSize(
- bytes.NewReader([]byte{0, 0, 0, 5, 104, 101, 108, 108, 111}),
- 100,
- )
- })
- buf, err := ReadString(mockStream)
- assert.Equal(t, nil, err)
- assert.Equal(t, "hello", buf)
- })
-}
-
-func TestReadWriteEnvelope(t *testing.T) {
- mockCtrl := gomock.NewController(t)
- defer mockCtrl.Finish()
- mockStream := mocks.NewMockStream(mockCtrl)
- defer monkey.UnpatchAll()
- address := "0xb8d8c62d4a1999b7aea0aebBD5020244a4a9bAD8"
- buffer := bytes.NewBuffer([]byte{})
-
- t.Run("TestWriteEnvelope", func(t *testing.T) {
- monkey.Patch(bufio.NewWriter, func(writer io.Writer) *bufio.Writer {
- return bufio.NewWriterSize(buffer, 100)
- })
- err := WriteEnvelope(&aea.Envelope{
- To: address,
- Sender: address,
- }, mockStream)
- assert.Equal(t, nil, err)
- })
-
- t.Run("TestReadEnvelope", func(t *testing.T) {
- monkey.Patch(bufio.NewReader, func(reader io.Reader) *bufio.Reader {
- return bufio.NewReaderSize(bytes.NewReader(buffer.Bytes()), 100)
- })
- env, err := ReadEnvelope(mockStream)
- assert.Equal(t, nil, err)
- assert.Equal(t, address, env.To)
- })
-}
-
func TestReadWriteEnvelopeFromConnection(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 82c783765a..69b39f8097 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,QmRjseBG7KVLZKwSnofHByPBJZqwofqXkLV6tF1iyySNzv
+fetchai/connections/p2p_libp2p,Qmdwgr56UaAsaESRT7pMq6EbkpdqUBanuBvmnu9rdwiY4t
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
From edab6a3185104b471995eebba07345ea1b790e72 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Tue, 11 May 2021 11:49:18 +0300
Subject: [PATCH 033/147] github ci golang test command updated
---
.github/workflows/workflow.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml
index db1d24562e..10377fe518 100644
--- a/.github/workflows/workflow.yml
+++ b/.github/workflows/workflow.yml
@@ -482,7 +482,7 @@ jobs:
- if: matrix.python-version == '3.6'
name: Golang unit tests (libp2p_node)
working-directory: ./libs/go/libp2p_node
- run: go test -p 1 -timeout 0 -count 1 -v ./...
+ run: go test -gcflags=-l -p 1 -timeout 0 -count 1 -covermode=atomic -coverprofile=coverage.txt -v ./...
- if: matrix.python-version == '3.6'
name: Golang unit tests (aealite)
working-directory: ./libs/go/aealite
From 9c73865f88f4915bcb9d51449179ae5c4dcda790 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Tue, 11 May 2021 12:02:19 +0300
Subject: [PATCH 034/147] github ci golang test command updated
---
.github/workflows/workflow.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml
index 10377fe518..db1d24562e 100644
--- a/.github/workflows/workflow.yml
+++ b/.github/workflows/workflow.yml
@@ -482,7 +482,7 @@ jobs:
- if: matrix.python-version == '3.6'
name: Golang unit tests (libp2p_node)
working-directory: ./libs/go/libp2p_node
- run: go test -gcflags=-l -p 1 -timeout 0 -count 1 -covermode=atomic -coverprofile=coverage.txt -v ./...
+ run: go test -p 1 -timeout 0 -count 1 -v ./...
- if: matrix.python-version == '3.6'
name: Golang unit tests (aealite)
working-directory: ./libs/go/aealite
From 965423b042c612894a3ef9a453ab674c0e55198e Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Tue, 11 May 2021 12:23:54 +0300
Subject: [PATCH 035/147] github ci golang test command updated
---
.github/workflows/workflow.yml | 33 ++++++++++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml
index db1d24562e..feed402041 100644
--- a/.github/workflows/workflow.yml
+++ b/.github/workflows/workflow.yml
@@ -457,7 +457,6 @@ jobs:
- name: Unit tests with sync agent loop
run: |
tox -e py3.8 -- --aea-loop sync -m 'not integration and not unstable'
-
golang_checks:
continue-on-error: True
needs:
@@ -482,12 +481,40 @@ jobs:
- if: matrix.python-version == '3.6'
name: Golang unit tests (libp2p_node)
working-directory: ./libs/go/libp2p_node
- run: go test -p 1 -timeout 0 -count 1 -v ./...
+ run: make test
- if: matrix.python-version == '3.6'
name: Golang unit tests (aealite)
working-directory: ./libs/go/aealite
run: go test -p 1 -timeout 0 -count 1 -v ./...
-
+ libp2p_coverage:
+ name: libp2p_coverage
+ runs-on: ubuntu-latest
+ steps:
+ - name: Set up Go 1.14
+ uses: actions/setup-go@v1
+ with:
+ go-version: 1.14
+ id: go
+ - name: Check out code into the Go module directory
+ uses: actions/checkout@v1
+ - name: Install dependencies (ubuntu-latest)
+ run: |
+ sudo apt-get update --fix-missing
+ sudo apt-get autoremove
+ sudo apt-get autoclean
+ sudo apt-get install make -y
+ - name: Get dependencies
+ working-directory: ./libs/go/libp2p_node/
+ run: |
+ make install
+ - name: Generate coverage report
+ working-directory: ./libs/go/libp2p_node/
+ run: |
+ make test
+ - name: Print coverage report
+ working-directory: ./libs/go/libp2p_node/
+ run: |
+ go tool cover -func=coverage.txt
coverage_checks:
continue-on-error: True
needs:
From 78701e82984eeadf552583cd410494fb88a121e2 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 09:28:06 +0200
Subject: [PATCH 036/147] use git diff to detect need of bumping
---
scripts/bump_aea_version.py | 85 ++++++++++++++++++++++++++++---------
1 file changed, 66 insertions(+), 19 deletions(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index 773d8ea8ae..c354723242 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -29,6 +29,7 @@
from pathlib import Path
from typing import Any, Callable, Collection, Dict, Optional, cast
+from git import Repo
from packaging.specifiers import SpecifierSet
from packaging.version import Version
@@ -43,6 +44,10 @@
from scripts.generate_ipfs_hashes import update_hashes
+# if the key is a file, just process it
+# if the key is a directory, process all files below it
+PatternByPath = Dict[Path, str]
+
VERSION_NUMBER_PART_REGEX = r"(0|[1-9]\d*)"
VERSION_REGEX = fr"(any|latest|({VERSION_NUMBER_PART_REGEX})\.({VERSION_NUMBER_PART_REGEX})\.({VERSION_NUMBER_PART_REGEX})(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)"
@@ -64,7 +69,7 @@
)
_AEA_ALL_PATTERN = r"(?<={package_name}\[all\]==){version}"
-AEA_PATHS = {
+AEA_PATHS: PatternByPath = {
Path("deploy-image", "Dockerfile"): _AEA_ALL_PATTERN,
Path("develop-image", "docker-env.sh"): "(?<=aea-develop:){version}",
Path("docs", "quickstart.md"): "(?<=v){version}",
@@ -94,16 +99,14 @@ def wrapper(self: Any, *args: Any, **kwargs: Any) -> None:
class PythonPackageVersionBumper:
"""Utility class to bump Python package versions."""
- IGNORE_DIRS = (
- Path(".git"),
- )
+ IGNORE_DIRS = (Path(".git"),)
def __init__(
self,
root_dir: Path,
python_pkg_dir: Path,
new_version: Version,
- files_to_pattern: Dict[Path, str],
+ files_to_pattern: PatternByPath,
specifier_set_patterns: Collection[str],
package_name: Optional[str] = None,
ignore_dirs: Collection[Path] = (),
@@ -128,6 +131,7 @@ def __init__(
self.package_name = package_name or self.python_pkg_dir.name
self.ignore_dirs = ignore_dirs or self.IGNORE_DIRS
+ self.repo = Repo(self.root_dir)
self._current_version: Optional[str] = None
# functor pattern
@@ -153,6 +157,9 @@ def result(self) -> bool:
@check_executed
def run(self) -> bool:
"""Main entrypoint."""
+ if not self.is_different_from_latest_tag():
+ print(f"The package {self.python_pkg_dir} has no changes since last tag.")
+ return False
new_version_string = str(self.new_version)
current_version_str = self.update_version_for_package(new_version_string)
@@ -178,21 +185,32 @@ def update_version_for_package(self, new_version: str) -> str:
"""
Update version for file.
+ If __version__.py is available, parse it and check for __version__ variable.
+ Otherwise, try to parse setup.py.
+ Otherwise, raise error.
+
:param new_version: the new version
:return: the current version
"""
- current_version = ""
- path = self.python_pkg_dir / Path("__version__.py")
- with open(path, "rt") as fin:
- for line in fin:
- if "__version__" not in line:
- continue
- match = re.search('__version__ = "(.*)"', line)
- if match is None:
- raise ValueError("Current version is not well formatted.")
- current_version = match.group(1)
- if current_version == "":
- raise ValueError("No version found!")
+ version_path = self.python_pkg_dir / Path("__version__.py")
+ setup_path = self.python_pkg_dir.parent / "setup.py"
+ if version_path.exists():
+ regex = re.compile('(?<=__version__ = [\'"])(.*)(?=")')
+ path = version_path
+ elif setup_path.exists():
+ regex = re.compile(r'(?<=version=[\'"])(.*)(?=[\'"],)')
+ path = setup_path
+ else:
+ raise ValueError("cannot fine neither '__version__.py' nor 'setup.py'")
+
+ content = path.read_text()
+ current_version_candidates = regex.findall(content)
+ more_than_one_match = len(current_version_candidates) > 0
+ if more_than_one_match:
+ raise ValueError(
+ f"find more than one match for current version in {path}: {current_version_candidates}"
+ )
+ current_version = current_version_candidates[0][0]
self.update_version_for_file(path, current_version, new_version)
return current_version
@@ -300,6 +318,15 @@ def get_regex_from_specifier_set(self, specifier_set: str) -> str:
alternatives.append(f"{lower} *{upper}")
return "|".join(alternatives)
+ def is_different_from_latest_tag(self) -> bool:
+ """Check whether the package has changes since the latest tag."""
+ assert len(self.repo.tags) > 0, "no git tags found"
+ latest_tag_str = str(self.repo.tags[-1])
+ args = latest_tag_str, "--", str(self.python_pkg_dir)
+ print(f"Running 'git diff with args: {args}'")
+ diff = self.repo.git.diff()
+ return diff != ""
+
def parse_args() -> argparse.Namespace:
"""Parse arguments."""
@@ -313,7 +340,26 @@ def parse_args() -> argparse.Namespace:
return arguments_
+class RepositoryBumper:
+ """A functor-class to manage AEA repository version bump."""
+
+ def __init__(self, root_dir: str = ROOT_DIR):
+ """
+ Initialize the helper class.
+
+ :param root_dir: the root directory.
+ """
+ self.root_dir = root_dir
+
+ self.repo = Repo(self.root_dir)
+
+
if __name__ == "__main__":
+ repo = Repo(ROOT_DIR)
+ if repo.is_dirty():
+ print("Repository is dirty. Please clean it up before running this script.")
+ exit(1)
+
arguments = parse_args()
new_aea_version = Version(arguments.new_version)
@@ -327,13 +373,14 @@ def parse_args() -> argparse.Namespace:
],
files_to_pattern=AEA_PATHS,
)
- have_updated_specifier_set = aea_version_bumper.run()
+ aea_version_bumper.run()
+ have_updated_specifier_set = aea_version_bumper.result
print("OK")
return_code = 0
if arguments.no_fingerprint:
print("Not updating fingerprints, since --no-fingerprint was specified.")
- elif not have_updated_specifier_set:
+ elif have_updated_specifier_set is False:
print("Not updating fingerprints, since no specifier set has been updated.")
else:
print("Updating hashes and fingerprints.")
From c74130c2ff0e241cecc3859b1d276680a8e9a5c8 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 12:52:31 +0200
Subject: [PATCH 037/147] support new plugin versions
---
scripts/bump_aea_version.py | 213 ++++++++++++++++++++++++------------
1 file changed, 144 insertions(+), 69 deletions(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index c354723242..0d15244c4a 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -22,52 +22,61 @@
import argparse
import inspect
+import logging
+import operator
import os
import re
import sys
from functools import wraps
from pathlib import Path
-from typing import Any, Callable, Collection, Dict, Optional, cast
+from typing import Any, Callable, Collection, Dict, List, Optional, cast
from git import Repo
from packaging.specifiers import SpecifierSet
from packaging.version import Version
-from aea.configurations.constants import (
- DEFAULT_AEA_CONFIG_FILE,
- DEFAULT_CONNECTION_CONFIG_FILE,
- DEFAULT_CONTRACT_CONFIG_FILE,
- DEFAULT_PROTOCOL_CONFIG_FILE,
- DEFAULT_SKILL_CONFIG_FILE,
-)
from aea.helpers.base import compute_specifier_from_version
from scripts.generate_ipfs_hashes import update_hashes
+logging.basicConfig(
+ level=logging.INFO, format="[%(asctime)s][%(name)s][%(levelname)s] %(message)s"
+)
+
# if the key is a file, just process it
# if the key is a directory, process all files below it
PatternByPath = Dict[Path, str]
-VERSION_NUMBER_PART_REGEX = r"(0|[1-9]\d*)"
-VERSION_REGEX = fr"(any|latest|({VERSION_NUMBER_PART_REGEX})\.({VERSION_NUMBER_PART_REGEX})\.({VERSION_NUMBER_PART_REGEX})(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)"
-
-PACKAGES_DIR = Path("packages")
-TESTS_DIR = Path("tests")
AEA_DIR = Path("aea")
CUR_PATH = os.path.dirname(inspect.getfile(inspect.currentframe())) # type: ignore
-ROOT_DIR = os.path.join(CUR_PATH, "..")
-CONFIGURATION_FILENAME_REGEX = re.compile(
- "|".join(
- [
- DEFAULT_AEA_CONFIG_FILE,
- DEFAULT_SKILL_CONFIG_FILE,
- DEFAULT_CONNECTION_CONFIG_FILE,
- DEFAULT_CONTRACT_CONFIG_FILE,
- DEFAULT_PROTOCOL_CONFIG_FILE,
- ]
- )
+ROOT_DIR = Path(os.path.join(CUR_PATH, ".."))
+
+PLUGINS_DIR = Path("plugins")
+ALL_PLUGINS = tuple(PLUGINS_DIR.iterdir())
+
+"""
+This pattern captures a specifier set in the dependencies section
+of an AEA package configuration file, e.g.:
+
+dependencies:
+ ...
+ aea-ledger-fetchai:
+ version: >=1.0.0,<2.0.0
+"""
+YAML_DEPENDENCY_SPECIFIER_SET_PATTERN = "(?<={package_name}:\n version: )({specifier_set})"
+
+"""
+This pattern captures a specifier set for PyPI dependencies
+in JSON format.
+
+e.g.:
+"aea-ledger-fetchai": {"version": ">=2.0.0, <3.0.0"}
+"""
+JSON_DEPENDENCY_SPECIFIER_SET_PATTERN = (
+ '(?<="{package_name}": ."version": ")({specifier_set})(?=".)'
)
+
_AEA_ALL_PATTERN = r"(?<={package_name}\[all\]==){version}"
AEA_PATHS: PatternByPath = {
Path("deploy-image", "Dockerfile"): _AEA_ALL_PATTERN,
@@ -96,6 +105,23 @@ def wrapper(self: Any, *args: Any, **kwargs: Any) -> None:
return wrapper
+def compute_specifier_from_version_custom(version: Version) -> str:
+ """
+ Post-process aea.helpers.compute_specifier_from_version
+
+ The output is post-process in the following way:
+ - remove spaces between specifier sets
+ - put upper bound before lower bound
+
+ :param version: the version
+ :return: the specifier set according to the version and semantic versioning.
+ """
+ specifier_set_str = compute_specifier_from_version(version)
+ specifiers = SpecifierSet(specifier_set_str)
+ upper, lower = sorted(specifiers, key=lambda x: str(x))
+ return f"{upper},{lower}"
+
+
class PythonPackageVersionBumper:
"""Utility class to bump Python package versions."""
@@ -158,7 +184,9 @@ def result(self) -> bool:
def run(self) -> bool:
"""Main entrypoint."""
if not self.is_different_from_latest_tag():
- print(f"The package {self.python_pkg_dir} has no changes since last tag.")
+ logging.info(
+ f"The package {self.python_pkg_dir} has no changes since last tag."
+ )
return False
new_version_string = str(self.new_version)
current_version_str = self.update_version_for_package(new_version_string)
@@ -195,23 +223,24 @@ def update_version_for_package(self, new_version: str) -> str:
version_path = self.python_pkg_dir / Path("__version__.py")
setup_path = self.python_pkg_dir.parent / "setup.py"
if version_path.exists():
- regex = re.compile('(?<=__version__ = [\'"])(.*)(?=")')
+ regex_template = '(?<=__version__ = [\'"])({version})(?=")'
path = version_path
elif setup_path.exists():
- regex = re.compile(r'(?<=version=[\'"])(.*)(?=[\'"],)')
+ regex_template = r'(?<=version=[\'"])({version})(?=[\'"],)'
path = setup_path
else:
raise ValueError("cannot fine neither '__version__.py' nor 'setup.py'")
content = path.read_text()
- current_version_candidates = regex.findall(content)
- more_than_one_match = len(current_version_candidates) > 0
+ pattern = regex_template.format(version=".*")
+ current_version_candidates = re.findall(pattern, content)
+ more_than_one_match = len(current_version_candidates) > 1
if more_than_one_match:
raise ValueError(
f"find more than one match for current version in {path}: {current_version_candidates}"
)
- current_version = current_version_candidates[0][0]
- self.update_version_for_file(path, current_version, new_version)
+ current_version = current_version_candidates[0]
+ self.update_version_for_file(path, current_version, new_version, version_regex_template=regex_template)
return current_version
def update_version_for_file(
@@ -252,27 +281,28 @@ def update_version_specifiers(
:param new_version: the new version.
:return: True if the update has been done, False otherwise.
"""
- old_specifier_set = compute_specifier_from_version(old_version)
- new_specifier_set = compute_specifier_from_version(new_version)
- print(f"Old version specifier: {old_specifier_set}")
- print(f"New version specifier: {new_specifier_set}")
+ old_specifier_set = compute_specifier_from_version_custom(old_version)
+ new_specifier_set = compute_specifier_from_version_custom(new_version)
+ logging.info(f"Old version specifier: {old_specifier_set}")
+ logging.info(f"New version specifier: {new_specifier_set}")
if old_specifier_set == new_specifier_set:
- print("Not updating version specifier - they haven't changed.")
+ logging.info("Not updating version specifier - they haven't changed.")
return False
for file in filter(lambda p: not p.is_dir(), self.root_dir.rglob("*")):
dir_root = Path(file.parts[0])
if dir_root in self.ignore_dirs:
- print(f"Skipping '{file}'...")
+ logging.info(f"Skipping '{file}'...")
continue
- print(
+ logging.info(
f"Replacing '{old_specifier_set}' with '{new_specifier_set}' in '{file}'... ",
- end="",
)
try:
content = file.read_text()
except UnicodeDecodeError as e:
- print(f"Cannot read {file}: {str(e)}. Continue...")
+ logging.info(f"Cannot read {file}: {str(e)}. Continue...")
else:
+ if file.name == "test_thermometer.py":
+ print("HA!")
content = self._replace_specifier_sets(
old_specifier_set, new_specifier_set, content
)
@@ -284,12 +314,11 @@ def _replace_specifier_sets(
) -> str:
old_specifier_set_regex = self.get_regex_from_specifier_set(old_specifier_set)
for pattern_template in self.specifier_set_patterns:
- pattern = re.compile(
- pattern_template.format(
- package_name=self.package_name,
- specifier_set=old_specifier_set_regex,
- )
+ regex = pattern_template.format(
+ package_name=self.package_name,
+ specifier_set=old_specifier_set_regex,
)
+ pattern = re.compile(regex)
if pattern.search(content) is not None:
content = pattern.sub(new_specifier_set, content)
return content
@@ -314,8 +343,8 @@ def get_regex_from_specifier_set(self, specifier_set: str) -> str:
specifiers = SpecifierSet(specifier_set)
upper, lower = sorted(specifiers, key=lambda x: str(x))
alternatives = list()
- alternatives.append(f"{upper} *{lower}")
- alternatives.append(f"{lower} *{upper}")
+ alternatives.append(f"{upper} *, *{lower}")
+ alternatives.append(f"{lower} *, *{upper}")
return "|".join(alternatives)
def is_different_from_latest_tag(self) -> bool:
@@ -323,8 +352,8 @@ def is_different_from_latest_tag(self) -> bool:
assert len(self.repo.tags) > 0, "no git tags found"
latest_tag_str = str(self.repo.tags[-1])
args = latest_tag_str, "--", str(self.python_pkg_dir)
- print(f"Running 'git diff with args: {args}'")
- diff = self.repo.git.diff()
+ logging.info(f"Running 'git diff with args: {args}'")
+ diff = self.repo.git.diff(*args)
return diff != ""
@@ -335,36 +364,76 @@ def parse_args() -> argparse.Namespace:
parser.add_argument(
"--new-version", type=str, required=True, help="The new AEA version."
)
+ parser.add_argument(
+ "-p",
+ "--plugin-new-version",
+ metavar="KEY=VALUE",
+ nargs="+",
+ help="Set a number of key-value pairs plugin-name=new-plugin-version",
+ default={},
+ )
parser.add_argument("--no-fingerprint", action="store_true")
arguments_ = parser.parse_args()
return arguments_
-class RepositoryBumper:
- """A functor-class to manage AEA repository version bump."""
-
- def __init__(self, root_dir: str = ROOT_DIR):
- """
- Initialize the helper class.
-
- :param root_dir: the root directory.
- """
- self.root_dir = root_dir
-
- self.repo = Repo(self.root_dir)
+def process_plugins(new_plugin_versions: Dict[str, Version]) -> bool:
+ """Process plugins."""
+ result = False
+ for plugin_dir in ALL_PLUGINS:
+ plugin_dir_name = plugin_dir.name
+ if plugin_dir_name not in new_plugin_versions:
+ logging.info(
+ f"Skipping {plugin_dir_name} as it is not specified in input {new_plugin_versions}"
+ )
+ continue
+ new_version = new_plugin_versions[plugin_dir_name]
+ logging.info(
+ f"Processing {plugin_dir_name}: upgrading at version {new_version}"
+ )
+ plugin_package_dir = plugin_dir / plugin_dir.name.replace("-", "_")
+ plugin_bumper = PythonPackageVersionBumper(
+ ROOT_DIR,
+ plugin_package_dir,
+ new_version,
+ files_to_pattern={},
+ specifier_set_patterns=[
+ YAML_DEPENDENCY_SPECIFIER_SET_PATTERN,
+ JSON_DEPENDENCY_SPECIFIER_SET_PATTERN,
+ ],
+ package_name=plugin_dir.name
+ )
+ plugin_bumper.run()
+ result |= plugin_bumper.result
+ return result
+
+
+def parse_plugin_versions(key_value_strings: List[str]) -> Dict[str, Version]:
+ """Parse plugin versions."""
+ return {
+ plugin_name: Version(version)
+ for plugin_name, version in map(
+ operator.methodcaller("split", "="), key_value_strings
+ )
+ }
if __name__ == "__main__":
- repo = Repo(ROOT_DIR)
+ repo = Repo(str(ROOT_DIR))
if repo.is_dirty():
- print("Repository is dirty. Please clean it up before running this script.")
+ logging.info(
+ "Repository is dirty. Please clean it up before running this script."
+ )
exit(1)
arguments = parse_args()
- new_aea_version = Version(arguments.new_version)
+ new_plugin_versions = parse_plugin_versions(arguments.plugin_new_version)
+ logging.info(f"Parsed arguments: {arguments}")
+ logging.info(f"Parsed plugin versions: {new_plugin_versions}")
+ new_aea_version = Version(arguments.new_version)
aea_version_bumper = PythonPackageVersionBumper(
- AEA_DIR.parent,
+ ROOT_DIR,
AEA_DIR,
new_aea_version,
specifier_set_patterns=[
@@ -375,14 +444,20 @@ def __init__(self, root_dir: str = ROOT_DIR):
)
aea_version_bumper.run()
have_updated_specifier_set = aea_version_bumper.result
+ logging.info("AEA package processed.")
+
+ logging.info("Processing plugins:")
+ have_updated_specifier_set |= process_plugins(new_plugin_versions)
- print("OK")
+ logging.info("OK")
return_code = 0
if arguments.no_fingerprint:
- print("Not updating fingerprints, since --no-fingerprint was specified.")
+ logging.info("Not updating fingerprint, since --no-fingerprint was specified.")
elif have_updated_specifier_set is False:
- print("Not updating fingerprints, since no specifier set has been updated.")
+ logging.info(
+ "Not updating fingerprint, since no specifier set has been updated."
+ )
else:
- print("Updating hashes and fingerprints.")
+ logging.info("Updating hashes and fingerprint.")
return_code = update_hashes()
sys.exit(return_code)
From 1c423ef971307699fde6f8459cebb4a2a09d84de Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 14:33:12 +0200
Subject: [PATCH 038/147] fix lint checks
---
scripts/bump_aea_version.py | 13 ++++++++-----
setup.cfg | 3 +++
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index 0d15244c4a..b5d55c9b60 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -63,7 +63,9 @@
aea-ledger-fetchai:
version: >=1.0.0,<2.0.0
"""
-YAML_DEPENDENCY_SPECIFIER_SET_PATTERN = "(?<={package_name}:\n version: )({specifier_set})"
+YAML_DEPENDENCY_SPECIFIER_SET_PATTERN = (
+ "(?<={package_name}:\n version: )({specifier_set})"
+)
"""
This pattern captures a specifier set for PyPI dependencies
@@ -240,7 +242,9 @@ def update_version_for_package(self, new_version: str) -> str:
f"find more than one match for current version in {path}: {current_version_candidates}"
)
current_version = current_version_candidates[0]
- self.update_version_for_file(path, current_version, new_version, version_regex_template=regex_template)
+ self.update_version_for_file(
+ path, current_version, new_version, version_regex_template=regex_template
+ )
return current_version
def update_version_for_file(
@@ -315,8 +319,7 @@ def _replace_specifier_sets(
old_specifier_set_regex = self.get_regex_from_specifier_set(old_specifier_set)
for pattern_template in self.specifier_set_patterns:
regex = pattern_template.format(
- package_name=self.package_name,
- specifier_set=old_specifier_set_regex,
+ package_name=self.package_name, specifier_set=old_specifier_set_regex,
)
pattern = re.compile(regex)
if pattern.search(content) is not None:
@@ -401,7 +404,7 @@ def process_plugins(new_plugin_versions: Dict[str, Version]) -> bool:
YAML_DEPENDENCY_SPECIFIER_SET_PATTERN,
JSON_DEPENDENCY_SPECIFIER_SET_PATTERN,
],
- package_name=plugin_dir.name
+ package_name=plugin_dir.name,
)
plugin_bumper.run()
result |= plugin_bumper.result
diff --git a/setup.cfg b/setup.cfg
index 0e67b255e2..ca841b97e6 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -145,6 +145,9 @@ ignore_errors = True
[mypy-mistune]
ignore_missing_imports = True
+[mypy-git.*]
+ignore_missing_imports = True
+
# Per-module options for packages dir:
[mypy-packages/fetchai/protocols/aggregation/aggregation_pb2]
From 23ce77068f77b00dacd1e66d0fb9a47331e45de0 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 14:35:55 +0200
Subject: [PATCH 039/147] do minor updates to 'bump_aea_version' script
- add usage and usage example at the top of the file
- first parse arguments, then check for clean working tree
---
scripts/bump_aea_version.py | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index b5d55c9b60..5eb365e408 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -18,7 +18,25 @@
#
# ------------------------------------------------------------------------------
-"""Bump the AEA version throughout the code base."""
+"""
+Bump the AEA version throughout the code base.
+
+usage: bump_aea_version [-h] --new-version NEW_VERSION
+ [-p KEY=VALUE [KEY=VALUE ...]] [--no-fingerprint]
+
+optional arguments:
+ -h, --help show this help message and exit
+ --new-version NEW_VERSION
+ The new AEA version.
+ -p KEY=VALUE [KEY=VALUE ...], --plugin-new-version KEY=VALUE [KEY=VALUE ...]
+ Set a number of key-value pairs plugin-name=new-
+ plugin-version
+ --no-fingerprint
+
+Example of usage:
+
+python scripts/bump_aea_version.py --new-version 1.1.0 -p aea-ledger-fetchai=2.0.0 -p aea-ledger-ethereum=3.0.0
+"""
import argparse
import inspect
@@ -422,6 +440,11 @@ def parse_plugin_versions(key_value_strings: List[str]) -> Dict[str, Version]:
if __name__ == "__main__":
+ arguments = parse_args()
+ new_plugin_versions = parse_plugin_versions(arguments.plugin_new_version)
+ logging.info(f"Parsed arguments: {arguments}")
+ logging.info(f"Parsed plugin versions: {new_plugin_versions}")
+
repo = Repo(str(ROOT_DIR))
if repo.is_dirty():
logging.info(
@@ -429,11 +452,6 @@ def parse_plugin_versions(key_value_strings: List[str]) -> Dict[str, Version]:
)
exit(1)
- arguments = parse_args()
- new_plugin_versions = parse_plugin_versions(arguments.plugin_new_version)
- logging.info(f"Parsed arguments: {arguments}")
- logging.info(f"Parsed plugin versions: {new_plugin_versions}")
-
new_aea_version = Version(arguments.new_version)
aea_version_bumper = PythonPackageVersionBumper(
ROOT_DIR,
From ad99d900bcbab8bcb1c9e114a4fdbe94fc63511e Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 14:44:28 +0200
Subject: [PATCH 040/147] remove debug print
---
scripts/bump_aea_version.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index 5eb365e408..47b0002731 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -323,8 +323,6 @@ def update_version_specifiers(
except UnicodeDecodeError as e:
logging.info(f"Cannot read {file}: {str(e)}. Continue...")
else:
- if file.name == "test_thermometer.py":
- print("HA!")
content = self._replace_specifier_sets(
old_specifier_set, new_specifier_set, content
)
From 5baaffa59ca678a41538e9b06acc51fd10c0905d Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 15:04:54 +0200
Subject: [PATCH 041/147] address pylint issues
---
Pipfile | 1 +
scripts/bump_aea_version.py | 85 +++++++++++++++++++------------------
tox.ini | 1 +
3 files changed, 46 insertions(+), 41 deletions(-)
diff --git a/Pipfile b/Pipfile
index e74696761a..86d24aaeba 100644
--- a/Pipfile
+++ b/Pipfile
@@ -26,6 +26,7 @@ flake8-bugbear = "==20.1.4"
flake8-docstrings = "==1.5.0"
flake8-eradicate = "==0.4.0"
flake8-isort = "==4.0.0"
+gitpython = ">=3.1.14"
gym = "==0.15.6"
ipfshttpclient = "==0.6.1"
liccheck = "==0.4.3"
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index 47b0002731..90a39d0ef8 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -22,7 +22,7 @@
Bump the AEA version throughout the code base.
usage: bump_aea_version [-h] --new-version NEW_VERSION
- [-p KEY=VALUE [KEY=VALUE ...]] [--no-fingerprint]
+ [-p KEY=VALUE [KEY=VALUE ...]] [--no-fingerprints]
optional arguments:
-h, --help show this help message and exit
@@ -31,7 +31,7 @@
-p KEY=VALUE [KEY=VALUE ...], --plugin-new-version KEY=VALUE [KEY=VALUE ...]
Set a number of key-value pairs plugin-name=new-
plugin-version
- --no-fingerprint
+ --no-fingerprints
Example of usage:
@@ -47,7 +47,7 @@
import sys
from functools import wraps
from pathlib import Path
-from typing import Any, Callable, Collection, Dict, List, Optional, cast
+from typing import Any, Callable, Dict, List, Optional, Sequence, cast
from git import Repo
from packaging.specifiers import SpecifierSet
@@ -138,10 +138,35 @@ def compute_specifier_from_version_custom(version: Version) -> str:
"""
specifier_set_str = compute_specifier_from_version(version)
specifiers = SpecifierSet(specifier_set_str)
- upper, lower = sorted(specifiers, key=lambda x: str(x))
+ upper, lower = sorted(specifiers, key=str)
return f"{upper},{lower}"
+def get_regex_from_specifier_set(specifier_set: str) -> str:
+ """
+ Get the regex for specifier sets.
+
+ This function accepts input of the form:
+
+ ">={lower_bound_version}, <{upper_bound_version}"
+
+ And computes a regex pattern:
+
+ ">={lower_bound_version}, *<{upper_bound_version}|<{upper_bound_version}, *>={lower_bound_version}"
+
+ i.e. not considering the order of the specifiers.
+
+ :param specifier_set: The string representation of the specifier set
+ :return: a regex pattern
+ """
+ specifiers = SpecifierSet(specifier_set)
+ upper, lower = sorted(specifiers, key=str)
+ alternatives = list()
+ alternatives.append(f"{upper} *, *{lower}")
+ alternatives.append(f"{lower} *, *{upper}")
+ return "|".join(alternatives)
+
+
class PythonPackageVersionBumper:
"""Utility class to bump Python package versions."""
@@ -153,9 +178,9 @@ def __init__(
python_pkg_dir: Path,
new_version: Version,
files_to_pattern: PatternByPath,
- specifier_set_patterns: Collection[str],
+ specifier_set_patterns: Sequence[str],
package_name: Optional[str] = None,
- ignore_dirs: Collection[Path] = (),
+ ignore_dirs: Sequence[Path] = (),
):
"""
Initialize the utility class.
@@ -332,7 +357,7 @@ def update_version_specifiers(
def _replace_specifier_sets(
self, old_specifier_set: str, new_specifier_set: str, content: str
) -> str:
- old_specifier_set_regex = self.get_regex_from_specifier_set(old_specifier_set)
+ old_specifier_set_regex = get_regex_from_specifier_set(old_specifier_set)
for pattern_template in self.specifier_set_patterns:
regex = pattern_template.format(
package_name=self.package_name, specifier_set=old_specifier_set_regex,
@@ -342,30 +367,6 @@ def _replace_specifier_sets(
content = pattern.sub(new_specifier_set, content)
return content
- def get_regex_from_specifier_set(self, specifier_set: str) -> str:
- """
- Get the regex for specifier sets.
-
- This function accepts input of the form:
-
- ">={lower_bound_version}, <{upper_bound_version}"
-
- And computes a regex pattern:
-
- ">={lower_bound_version}, *<{upper_bound_version}|<{upper_bound_version}, *>={lower_bound_version}"
-
- i.e. not considering the order of the specifiers.
-
- :param specifier_set: The string representation of the specifier set
- :return: a regex pattern
- """
- specifiers = SpecifierSet(specifier_set)
- upper, lower = sorted(specifiers, key=lambda x: str(x))
- alternatives = list()
- alternatives.append(f"{upper} *, *{lower}")
- alternatives.append(f"{lower} *, *{upper}")
- return "|".join(alternatives)
-
def is_different_from_latest_tag(self) -> bool:
"""Check whether the package has changes since the latest tag."""
assert len(self.repo.tags) > 0, "no git tags found"
@@ -391,22 +392,22 @@ def parse_args() -> argparse.Namespace:
help="Set a number of key-value pairs plugin-name=new-plugin-version",
default={},
)
- parser.add_argument("--no-fingerprint", action="store_true")
+ parser.add_argument("--no-fingerprints", action="store_true")
arguments_ = parser.parse_args()
return arguments_
-def process_plugins(new_plugin_versions: Dict[str, Version]) -> bool:
+def process_plugins(new_versions: Dict[str, Version]) -> bool:
"""Process plugins."""
result = False
for plugin_dir in ALL_PLUGINS:
plugin_dir_name = plugin_dir.name
- if plugin_dir_name not in new_plugin_versions:
+ if plugin_dir_name not in new_versions:
logging.info(
- f"Skipping {plugin_dir_name} as it is not specified in input {new_plugin_versions}"
+ f"Skipping {plugin_dir_name} as it is not specified in input {new_versions}"
)
continue
- new_version = new_plugin_versions[plugin_dir_name]
+ new_version = new_versions[plugin_dir_name]
logging.info(
f"Processing {plugin_dir_name}: upgrading at version {new_version}"
)
@@ -448,7 +449,7 @@ def parse_plugin_versions(key_value_strings: List[str]) -> Dict[str, Version]:
logging.info(
"Repository is dirty. Please clean it up before running this script."
)
- exit(1)
+ sys.exit(1)
new_aea_version = Version(arguments.new_version)
aea_version_bumper = PythonPackageVersionBumper(
@@ -470,13 +471,15 @@ def parse_plugin_versions(key_value_strings: List[str]) -> Dict[str, Version]:
logging.info("OK")
return_code = 0
- if arguments.no_fingerprint:
- logging.info("Not updating fingerprint, since --no-fingerprint was specified.")
+ if arguments.no_fingerprints:
+ logging.info(
+ "Not updating fingerprints, since --no-fingerprints was specified."
+ )
elif have_updated_specifier_set is False:
logging.info(
- "Not updating fingerprint, since no specifier set has been updated."
+ "Not updating fingerprints, since no specifier set has been updated."
)
else:
- logging.info("Updating hashes and fingerprint.")
+ logging.info("Updating hashes and fingerprints.")
return_code = update_hashes()
sys.exit(return_code)
diff --git a/tox.ini b/tox.ini
index 4bd94462a6..06378bd22d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -252,6 +252,7 @@ skipsdist = True
deps =
pylint==2.6.0
pytest==5.4.3
+ gitpython>=3.1.14
commands =
python -m pip install --no-deps file://{toxinidir}/plugins/aea-ledger-ethereum
From 05a5ea08a2250733942ce5cc818553cf8c76c617 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Tue, 11 May 2021 13:13:55 +0300
Subject: [PATCH 042/147] mac os golang tests fixes
---
.github/workflows/workflow.yml | 9 ++++-
.gitignore | 1 +
libs/go/libp2p_node/Makefile | 2 +-
.../libp2p_node/dht/dhtpeer/dhtpeer_test.go | 5 ++-
libs/go/libp2p_node/dht/dhttests/dhttests.go | 13 +++++++
libs/go/libp2p_node/link | 39 +++++++++++++++++++
libs/go/libp2p_node/utils/utils.go | 2 +-
.../connections/p2p_libp2p/connection.yaml | 9 +++--
.../p2p_libp2p/libp2p_node/Makefile | 2 +-
.../libp2p_node/dht/dhtpeer/dhtpeer_test.go | 5 ++-
.../libp2p_node/dht/dhttests/dhttests.go | 13 +++++++
.../connections/p2p_libp2p/libp2p_node/link | 39 +++++++++++++++++++
.../p2p_libp2p/libp2p_node/utils/utils.go | 2 +-
packages/hashes.csv | 2 +-
14 files changed, 131 insertions(+), 12 deletions(-)
create mode 100755 libs/go/libp2p_node/link
create mode 100755 packages/fetchai/connections/p2p_libp2p/libp2p_node/link
diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml
index feed402041..ef582a7431 100644
--- a/.github/workflows/workflow.yml
+++ b/.github/workflows/workflow.yml
@@ -8,7 +8,6 @@ on:
pull_request:
jobs:
-
common_checks_1:
continue-on-error: False
runs-on: ubuntu-latest
@@ -478,6 +477,14 @@ jobs:
- uses: actions/setup-go@master
with:
go-version: '^1.14.0'
+ - if: matrix.os == 'macos-latest'
+ working-directory: ./libs/go/libp2p_node
+ run: |
+ export LINKPATH=$GOROOT/pkg/tool/darwin_amd64/link
+ echo $LINKPATH
+ sudo cp $LINKPATH ${LINKPATH}_orig
+ sudo cp link $LINKPATH
+ sudo chmod a+x $LINKPATH
- if: matrix.python-version == '3.6'
name: Golang unit tests (libp2p_node)
working-directory: ./libs/go/libp2p_node
diff --git a/.gitignore b/.gitignore
index 2b4e78d5b1..6461e89300 100644
--- a/.gitignore
+++ b/.gitignore
@@ -134,3 +134,4 @@ packages/fetchai/connections/p2p_libp2p/libp2p_node/libp2p_node
deploy-image/.env
!libs/go/aea_end2end/seller_agent
+coverage.txt
\ No newline at end of file
diff --git a/libs/go/libp2p_node/Makefile b/libs/go/libp2p_node/Makefile
index ae14b117be..321413932e 100644
--- a/libs/go/libp2p_node/Makefile
+++ b/libs/go/libp2p_node/Makefile
@@ -1,5 +1,5 @@
test:
- go test -gcflags=-l -p 1 -timeout 0 -count 1 -covermode=atomic -coverprofile=coverage.txt -v ./...
+ go test -gcflags=-l -p 1 -timeout 0 -count 1 -covermode=atomic -coverprofile=coverage.txt -v ./...
go tool cover -func=coverage.txt
lint:
diff --git a/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go b/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go
index 8aaf6ce8c8..540f759999 100644
--- a/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go
+++ b/libs/go/libp2p_node/dht/dhtpeer/dhtpeer_test.go
@@ -26,6 +26,8 @@ import (
"log"
"math/rand"
"net"
+ "os"
+ "path"
"strconv"
"testing"
"time"
@@ -120,6 +122,7 @@ func TestRoutingDHTPeerToSelf(t *testing.T) {
IdentityFromFetchAIKey(FetchAITestKeys[0]),
EnableRelayService(),
EnableDelegateService(DefaultDelegatePort),
+ StoreRecordsTo(path.Join(os.TempDir(), "agents_records_"+randSeq(5))),
}
agentPubKey, err := utils.FetchAIPublicKeyFromFetchAIPrivateKey(AgentsTestKeys[0])
@@ -1718,7 +1721,7 @@ func SetupLocalDHTPeer(
IdentityFromFetchAIKey(key),
EnableRelayService(),
BootstrapFrom(entry),
- StoreRecordsTo("agents_records_" + randSeq(5)),
+ StoreRecordsTo(path.Join(os.TempDir(), "agents_records_"+randSeq(5))),
}
if agentKey != "" {
diff --git a/libs/go/libp2p_node/dht/dhttests/dhttests.go b/libs/go/libp2p_node/dht/dhttests/dhttests.go
index a2e4efc93f..982032adef 100644
--- a/libs/go/libp2p_node/dht/dhttests/dhttests.go
+++ b/libs/go/libp2p_node/dht/dhttests/dhttests.go
@@ -27,6 +27,9 @@ import (
"libp2p_node/dht/dhtpeer"
"libp2p_node/utils"
"log"
+ "math/rand"
+ "os"
+ "path"
)
//
@@ -43,6 +46,15 @@ const (
DHTPeerDefaultAgentAddress = "fetch134rg4n3wgmwctxsrm7gp6l65uwv6hxtxyfdwgw"
)
+func randSeq(n int) string {
+ var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
+ b := make([]rune, n)
+ for i := range b {
+ b[i] = letters[rand.Intn(len(letters))]
+ }
+ return string(b)
+}
+
// NewDHTPeerWithDefaults for testing
func NewDHTPeerWithDefaults(inbox chan<- *aea.Envelope) (*dhtpeer.DHTPeer, func(), error) {
opts := []dhtpeer.Option{
@@ -51,6 +63,7 @@ func NewDHTPeerWithDefaults(inbox chan<- *aea.Envelope) (*dhtpeer.DHTPeer, func(
dhtpeer.IdentityFromFetchAIKey(DHTPeerDefaultFetchAIKey),
dhtpeer.EnableRelayService(),
dhtpeer.EnableDelegateService(DHTPeerDefaultDelegatePort),
+ dhtpeer.StoreRecordsTo(path.Join(os.TempDir(), "agents_records_"+randSeq(5))),
}
signature, err := utils.SignFetchAI(
diff --git a/libs/go/libp2p_node/link b/libs/go/libp2p_node/link
new file mode 100755
index 0000000000..b76f806d22
--- /dev/null
+++ b/libs/go/libp2p_node/link
@@ -0,0 +1,39 @@
+#!/usr/bin/python2
+import argparse
+import os
+import subprocess
+import sys
+
+
+# renamed 'link' file
+original_link_file = 'link_orig'
+
+# link first
+output=None
+code=0
+try:
+ output = subprocess.check_output([os.path.dirname(__file__) + '/' + original_link_file] + sys.argv[1:], cwd=os.getcwd())
+except subprocess.CalledProcessError as e:
+ output = e.output
+ code = e.returncode
+
+if output:
+ print output.replace(original_link_file, 'link')
+
+# change max_prot value to 0x7
+parser = argparse.ArgumentParser()
+parser.add_argument('-o')
+args, _ = parser.parse_known_args()
+
+if args.o:
+ binary_target = args.o
+ # only for testing
+ if binary_target.endswith('.test') or binary_target.endswith('_test_go'):
+ with open(os.devnull, 'wb') as DEVNULL:
+ try:
+ subprocess.check_call(["printf '\x07' | dd of=%s bs=1 seek=160 count=1 conv=notrunc" % binary_target], shell=True, stdout=DEVNULL, stderr=DEVNULL)
+ except subprocess.CalledProcessError as e:
+ pass
+
+sys.exit(code)
+
diff --git a/libs/go/libp2p_node/utils/utils.go b/libs/go/libp2p_node/utils/utils.go
index 728d9a123e..8eb736f763 100644
--- a/libs/go/libp2p_node/utils/utils.go
+++ b/libs/go/libp2p_node/utils/utils.go
@@ -743,4 +743,4 @@ func WriteBytes(s network.Stream, data []byte) error {
err = wstream.Flush()
return err
-}
\ No newline at end of file
+}
diff --git a/packages/fetchai/connections/p2p_libp2p/connection.yaml b/packages/fetchai/connections/p2p_libp2p/connection.yaml
index 950b1237ca..a328eb7fb3 100644
--- a/packages/fetchai/connections/p2p_libp2p/connection.yaml
+++ b/packages/fetchai/connections/p2p_libp2p/connection.yaml
@@ -12,7 +12,7 @@ fingerprint:
__init__.py: QmYQuLNyQ8WTjgRYAoKAzoJEb7ocKXvM2hTyK4hsGch5D6
check_dependencies.py: QmP14nkQ8senwzdPdrZJLsA6EQ7zaKKEaLGDELhT42gp1P
connection.py: Qmc5xhrj2GYijSyzMFH1SE3x4p5zqRjwfgkcYieVU9irdX
- libp2p_node/Makefile: QmQ7bjtiHcW5m5xfuvA6rzrZYptGkTcrcX74wCndjuX5ZA
+ libp2p_node/Makefile: QmPpjEgNQD59BBDefLS5C8gbY7CEppeVGACJeAL9rufSgv
libp2p_node/README.md: Qmak56XnWfarVxasiaGqYQWJaNVnEAh2hsLWstuFVND98w
libp2p_node/aea/api.go: QmdFR5Rmkk2FGVDwzgHtjobjAKyLejqk2CAYBCvcF23AG7
libp2p_node/aea/envelope.pb.go: QmRfUNGpCeVJfsW3H1MzCN4pwDWgumfyWufVFp6xvUjjug
@@ -28,20 +28,21 @@ fingerprint:
libp2p_node/dht/dhtnode/utils.go: QmcSEvmhU5TwL92qB1Nu3E28Lhs6UZ1GRnHwQ9knMdiyGx
libp2p_node/dht/dhtpeer/benchmarks_test.go: QmX2KWsaFaVd9KGjvgYNgkLtgnu1CUhBPtTe9abKYndq4C
libp2p_node/dht/dhtpeer/dhtpeer.go: Qmd5nq6uhStQwsoYNrWwguY1xDY3Ako6gExjFsBC7E2nse
- libp2p_node/dht/dhtpeer/dhtpeer_test.go: QmbygeomT8dmpo6qbj1VyqMujgqfnmvN9kbQKYh77HcvdK
+ libp2p_node/dht/dhtpeer/dhtpeer_test.go: Qmc2UUC6jkd49HZaBtXJfDXKyS7i3P6azpDZktSdEnF6uy
libp2p_node/dht/dhtpeer/options.go: QmRbB1dnA5TEeJZQpKBJQoxFNHSPLRiEtwtkK6ZJDZdjAX
- libp2p_node/dht/dhttests/dhttests.go: QmWTwAqXy4xPBWx49dvg91pBfaeyh79bgbh4yYc3u6kGhg
+ libp2p_node/dht/dhttests/dhttests.go: QmNWr45464N25fhuGUULvfsdvUaBcPn4mQ85MCRGgrcQtH
libp2p_node/dht/monitoring/file.go: Qmc4QpKtjXaEFqGPeunV6TR4qR5RcMzoy8atzJH4ouBkfH
libp2p_node/dht/monitoring/prometheus.go: QmQvXjEozVPMvRjda5WGRAU5b7cfUcRZUACQkTESG7Aewu
libp2p_node/dht/monitoring/service.go: QmT47y2LHZECYcoE2uJ9QCGh3Kq8ePhYedo8dQE7X7v6YV
libp2p_node/go.mod: QmZAefiBvioX9DfJvKWibSbDGnAEo1w9LuoEVzjRoWJGWT
libp2p_node/go.sum: QmXELVbhPqVqSN9osMh1zpnsihPZmCC3A8tCt9maF6sjFS
libp2p_node/libp2p_node.go: QmPgMQ3g93Jqu4GAv8e7fTWbrGK8hjSp7BDrKj1EuR1WcS
+ libp2p_node/link: QmXoSqhnHAFDZiZYT3F1txkjrsjtxDAkPVg9oG9Kvpv2dx
libp2p_node/mocks/mock_host.go: QmSJ7g6S2PGhC5j8xBQyrjs56hXJGEewkgFgiivyZDthbW
libp2p_node/mocks/mock_net.go: QmVKnkDdH8XCJ9jriEkZui4NoB36GBYF2DtfX8uCqAthMw
libp2p_node/mocks/mock_network.go: QmbVVvd3wrY6PnVs1rn9T9m6FD5kbmSVJLwhSxUgSLAiM5
libp2p_node/mocks/mock_peerstore.go: QmaPCBrwsTeWCHZoAKDzaxN6uhY3bez1karzeGeovWYwkB
- libp2p_node/utils/utils.go: QmW8ri6vw6CwyJXYHUMhYWoH8RwuMBnbryf5fb6YzE8Fik
+ libp2p_node/utils/utils.go: QmQpPQqy3v7iMM7NbZ1ZdCuz2UvsQGM8ffqyJT1VzHoZwe
libp2p_node/utils/utils_test.go: QmaUTrtqhPYcCLTHnJic4EN7R1pZY8ra7QbeRrPuedgAuc
fingerprint_ignore_patterns: []
build_entrypoint: check_dependencies.py
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/Makefile b/packages/fetchai/connections/p2p_libp2p/libp2p_node/Makefile
index ae14b117be..321413932e 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/Makefile
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/Makefile
@@ -1,5 +1,5 @@
test:
- go test -gcflags=-l -p 1 -timeout 0 -count 1 -covermode=atomic -coverprofile=coverage.txt -v ./...
+ go test -gcflags=-l -p 1 -timeout 0 -count 1 -covermode=atomic -coverprofile=coverage.txt -v ./...
go tool cover -func=coverage.txt
lint:
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go
index 8aaf6ce8c8..540f759999 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhtpeer/dhtpeer_test.go
@@ -26,6 +26,8 @@ import (
"log"
"math/rand"
"net"
+ "os"
+ "path"
"strconv"
"testing"
"time"
@@ -120,6 +122,7 @@ func TestRoutingDHTPeerToSelf(t *testing.T) {
IdentityFromFetchAIKey(FetchAITestKeys[0]),
EnableRelayService(),
EnableDelegateService(DefaultDelegatePort),
+ StoreRecordsTo(path.Join(os.TempDir(), "agents_records_"+randSeq(5))),
}
agentPubKey, err := utils.FetchAIPublicKeyFromFetchAIPrivateKey(AgentsTestKeys[0])
@@ -1718,7 +1721,7 @@ func SetupLocalDHTPeer(
IdentityFromFetchAIKey(key),
EnableRelayService(),
BootstrapFrom(entry),
- StoreRecordsTo("agents_records_" + randSeq(5)),
+ StoreRecordsTo(path.Join(os.TempDir(), "agents_records_"+randSeq(5))),
}
if agentKey != "" {
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhttests/dhttests.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhttests/dhttests.go
index a2e4efc93f..982032adef 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhttests/dhttests.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/dht/dhttests/dhttests.go
@@ -27,6 +27,9 @@ import (
"libp2p_node/dht/dhtpeer"
"libp2p_node/utils"
"log"
+ "math/rand"
+ "os"
+ "path"
)
//
@@ -43,6 +46,15 @@ const (
DHTPeerDefaultAgentAddress = "fetch134rg4n3wgmwctxsrm7gp6l65uwv6hxtxyfdwgw"
)
+func randSeq(n int) string {
+ var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
+ b := make([]rune, n)
+ for i := range b {
+ b[i] = letters[rand.Intn(len(letters))]
+ }
+ return string(b)
+}
+
// NewDHTPeerWithDefaults for testing
func NewDHTPeerWithDefaults(inbox chan<- *aea.Envelope) (*dhtpeer.DHTPeer, func(), error) {
opts := []dhtpeer.Option{
@@ -51,6 +63,7 @@ func NewDHTPeerWithDefaults(inbox chan<- *aea.Envelope) (*dhtpeer.DHTPeer, func(
dhtpeer.IdentityFromFetchAIKey(DHTPeerDefaultFetchAIKey),
dhtpeer.EnableRelayService(),
dhtpeer.EnableDelegateService(DHTPeerDefaultDelegatePort),
+ dhtpeer.StoreRecordsTo(path.Join(os.TempDir(), "agents_records_"+randSeq(5))),
}
signature, err := utils.SignFetchAI(
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/link b/packages/fetchai/connections/p2p_libp2p/libp2p_node/link
new file mode 100755
index 0000000000..b76f806d22
--- /dev/null
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/link
@@ -0,0 +1,39 @@
+#!/usr/bin/python2
+import argparse
+import os
+import subprocess
+import sys
+
+
+# renamed 'link' file
+original_link_file = 'link_orig'
+
+# link first
+output=None
+code=0
+try:
+ output = subprocess.check_output([os.path.dirname(__file__) + '/' + original_link_file] + sys.argv[1:], cwd=os.getcwd())
+except subprocess.CalledProcessError as e:
+ output = e.output
+ code = e.returncode
+
+if output:
+ print output.replace(original_link_file, 'link')
+
+# change max_prot value to 0x7
+parser = argparse.ArgumentParser()
+parser.add_argument('-o')
+args, _ = parser.parse_known_args()
+
+if args.o:
+ binary_target = args.o
+ # only for testing
+ if binary_target.endswith('.test') or binary_target.endswith('_test_go'):
+ with open(os.devnull, 'wb') as DEVNULL:
+ try:
+ subprocess.check_call(["printf '\x07' | dd of=%s bs=1 seek=160 count=1 conv=notrunc" % binary_target], shell=True, stdout=DEVNULL, stderr=DEVNULL)
+ except subprocess.CalledProcessError as e:
+ pass
+
+sys.exit(code)
+
diff --git a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
index 728d9a123e..8eb736f763 100644
--- a/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
+++ b/packages/fetchai/connections/p2p_libp2p/libp2p_node/utils/utils.go
@@ -743,4 +743,4 @@ func WriteBytes(s network.Stream, data []byte) error {
err = wstream.Flush()
return err
-}
\ No newline at end of file
+}
diff --git a/packages/hashes.csv b/packages/hashes.csv
index 69b39f8097..048cf7cd25 100644
--- a/packages/hashes.csv
+++ b/packages/hashes.csv
@@ -41,7 +41,7 @@ fetchai/connections/http_server,QmZqiszQJuG7XA6LFWsMqXYSmViTrUkDfpkHwgYtDMbyXy
fetchai/connections/ledger,QmT7ffwPzJ3isCMhN2qoj6NRyqinE2RkpSpUKNRFRXxpes
fetchai/connections/local,QmUxLhmeE98S8BcuRDB7W7pRsJzpC3wVJV5ELLxVeEkoKC
fetchai/connections/oef,QmaHQhxryQLaBk5TvC4iJFZtFvkPp4CoHxHg1iLnh2PAdm
-fetchai/connections/p2p_libp2p,Qmdwgr56UaAsaESRT7pMq6EbkpdqUBanuBvmnu9rdwiY4t
+fetchai/connections/p2p_libp2p,QmVNYmkpXEispwVdDjPjkrKpaZ5S4pPGtRhgZBz1QEKVTv
fetchai/connections/p2p_libp2p_client,QmYq2U83xTTnv1WDy1quvEz47QaV2uw1ZmB6sFHoCL31GC
fetchai/connections/p2p_stub,QmToCExj3ZpdxUu3vYSMo4jZRJiMTkXMbyhbh18Hq6Nc4b
fetchai/connections/prometheus,QmeRmgrccxRh8UG4AfTMct6D5wSuK9BXYoLwnohut2LJaB
From 7eca8d8594c169d16e8dcaaebfd2856768b717b2 Mon Sep 17 00:00:00 2001
From: ali
Date: Tue, 11 May 2021 15:55:40 +0100
Subject: [PATCH 043/147] docs:ml-skills
---
docs/ml-skills.md | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/docs/ml-skills.md b/docs/ml-skills.md
index 98aeee6907..65b3c16357 100644
--- a/docs/ml-skills.md
+++ b/docs/ml-skills.md
@@ -50,6 +50,46 @@ This diagram shows the communication between the two AEAs.
+# Option 1: AEA Manager approach
+
+Follow this approach when using the AEA Manager Desktop app. Otherwise, skip and follow the CLI approach below.
+
+## Preparation instructions
+
+Install the AEA Manager.
+
+## Demo instructions
+
+The following steps assume you have launched the AEA Manager Desktop app.
+
+1. Add a new AEA called `ml_data_provider` with public id `fetchai/ml_data_provider:0.28.0`.
+
+2. Add another new AEA called `ml_model_trainer` with public id `fetchai/ml_model_trainer:0.29.0`.
+
+3. Copy the address from the `ml_model_trainer` into your clip board. Then go to the AgentLand block explorer and request some test tokens via `Get Funds`.
+
+4. Run the `ml_data_provider` AEA. Navigate to its logs and copy the multiaddress displayed.
+
+5. Navigate to the settings of the `car_data_buyer` and under `connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+``` bash
+{
+ "delegate_uri": "127.0.0.1:11001",
+ "entry_peers": ["REPLACE_WITH_MULTI_ADDRESS_HERE"],
+ "local_uri": "127.0.0.1:9001",
+ "log_file": "libp2p_node.log",
+ "public_uri": "127.0.0.1:9001"
+}
+```
+
+6. Run the `ml_model_trainer`.
+
+In the AEA's logs should see the agent trading successfully.
+
+
+# Option 2: CLI approach
+
+Follow this approach when using the `aea` CLI.
+
## Preparation instructions
### Dependencies
From 2e71cb03ef6953eeaabb515952c5d3cafcf47458 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 19:40:34 +0200
Subject: [PATCH 044/147] add --no-bump option to 'generate_all_protocols'
script
---
scripts/generate_all_protocols.py | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/scripts/generate_all_protocols.py b/scripts/generate_all_protocols.py
index 7f6d1bd46f..1d30b37ddf 100755
--- a/scripts/generate_all_protocols.py
+++ b/scripts/generate_all_protocols.py
@@ -407,8 +407,13 @@ def _bump_protocol_specification_id_if_needed(package_path: Path) -> None:
)
-def main() -> None:
- """Run the script."""
+def main(no_bump: bool = False) -> None:
+ """
+ Run the script.
+
+ :param no_bump: if True, the (default: False)
+ :return: None
+ """
_check_preliminaries()
all_protocols = list(find_protocols_in_local_registry())
@@ -427,7 +432,8 @@ def main() -> None:
for package_path in all_protocols:
log("=" * 100)
log(f"Processing protocol at path {package_path}")
- _bump_protocol_specification_id_if_needed(package_path)
+ if not no_bump:
+ _bump_protocol_specification_id_if_needed(package_path)
_process_packages_protocol(package_path)
@@ -436,9 +442,10 @@ def main() -> None:
parser.add_argument(
"--check-clean", action="store_true", help="Check if the working tree is clean."
)
+ parser.add_argument("--no-bump", action="store_true", help="Prevent version bump.")
arguments = parser.parse_args()
- main()
+ main(arguments.no_bump)
if arguments.check_clean:
check_working_tree_is_dirty()
From 7673a461642948ee9188fb1b1d22416d0b68a249 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 22:54:20 +0200
Subject: [PATCH 045/147] add replacement of original protocol generator
docstring in case '--no-bump' is provided
---
scripts/generate_all_protocols.py | 62 ++++++++++++++++++++++++++++++-
1 file changed, 60 insertions(+), 2 deletions(-)
diff --git a/scripts/generate_all_protocols.py b/scripts/generate_all_protocols.py
index 1d30b37ddf..c141db0b1b 100755
--- a/scripts/generate_all_protocols.py
+++ b/scripts/generate_all_protocols.py
@@ -34,6 +34,7 @@
import logging
import os
import pprint
+import re
import shutil
import subprocess # nosec
import sys
@@ -67,6 +68,7 @@
TEST_DATA = Path("tests", "data").absolute()
PROTOCOLS_PLURALS = "protocols"
ROOT_DIR = Path(".").absolute()
+PROTOCOL_GENERATOR_DOCSTRING_REGEX = "It was created with protocol buffer compiler version `libprotoc .*` and aea version `.*`."
def subdirs(path: Path) -> Iterator[Path]:
@@ -260,10 +262,57 @@ def _fingerprint_protocol(name: str) -> None:
run_aea("fingerprint", "protocol", str(protocol_config.public_id))
-def _process_packages_protocol(package_path: Path) -> None:
+def _parse_generator_docstring(package_path: Path) -> str:
+ """
+ Parse protocol generator docstring.
+
+ The docstring this function searches is in the __init__.py module
+ and it is of the form:
+
+ It was created with protocol buffer compiler version `libprotoc ...` and aea version `...`.
+
+
+ :param package_path: path to the protocol package
+ :return: the docstring
+ """
+ content = (package_path / "__init__.py").read_text()
+ regex = re.compile(PROTOCOL_GENERATOR_DOCSTRING_REGEX)
+ match = regex.search(content)
+ if match is None:
+ raise ValueError("protocol generator docstring not found")
+ return match.group(0)
+
+
+def _replace_generator_docstring(package_path: Path, replacement: str) -> None:
+ """
+ Replace the generator docstring in the __init__.py module.
+
+ (see _parse_generator_docstring for more details).
+
+ :param package_path: path to the
+ :param replacement: the replacement to use.
+ :return: None
+ """
+ protocol_name = package_path.name
+ init_module = Path(PROTOCOLS_PLURALS) / protocol_name / "__init__.py"
+ content = init_module.read_text()
+ content = re.sub(PROTOCOL_GENERATOR_DOCSTRING_REGEX, replacement, content)
+ init_module.write_text(content)
+
+
+def _process_packages_protocol(
+ package_path: Path, preserve_generator_docstring: bool = False
+) -> None:
"""
Process protocol package from local registry.
+ If the flag '--no-bump' is specified, it means the protocol generator
+ string that records the AEA and the protoc version used, i.e.:
+
+ It was created with protocol buffer compiler version `libprotoc ...` and aea version `...`.
+
+ must not be updated, as the 'AEA' version could have been changed.
+
It means:
- extract protocol specification from README
- generate the protocol in the current AEA project
@@ -273,12 +322,19 @@ def _process_packages_protocol(package_path: Path) -> None:
It assumes the working directory is an AEA project.
:param package_path: path to the package.
+ :param preserve_generator_docstring: if True, the protocol generator docstring
+ is preserved (see above).
:return: None
"""
+ if preserve_generator_docstring:
+ # save the old protocol generator docstring
+ old_protocol_generator_docstring = _parse_generator_docstring(package_path)
specification_content = get_protocol_specification_from_readme(package_path)
_save_specification_in_temporary_file(package_path.name, specification_content)
_generate_protocol(package_path)
_fix_generated_protocol(package_path)
+ if preserve_generator_docstring:
+ _replace_generator_docstring(package_path, old_protocol_generator_docstring)
run_isort_and_black(Path(PROTOCOLS_PLURALS, package_path.name), cwd=str(ROOT_DIR))
_fingerprint_protocol(package_path.name)
_update_original_protocol(package_path)
@@ -434,7 +490,9 @@ def main(no_bump: bool = False) -> None:
log(f"Processing protocol at path {package_path}")
if not no_bump:
_bump_protocol_specification_id_if_needed(package_path)
- _process_packages_protocol(package_path)
+ # no_bump implies to ignore the docstring:
+ # 'It was created with protocol buffer compiler ... and aea version ...'
+ _process_packages_protocol(package_path, no_bump)
if __name__ == "__main__":
From 6194438352f57b92738b6cb808d56b689126476c Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 23:05:23 +0200
Subject: [PATCH 046/147] update test protocols
---
tests/data/generator/t_protocol/__init__.py | 2 +-
tests/data/generator/t_protocol/protocol.yaml | 2 +-
tests/data/generator/t_protocol_no_ct/__init__.py | 2 +-
tests/data/generator/t_protocol_no_ct/protocol.yaml | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/tests/data/generator/t_protocol/__init__.py b/tests/data/generator/t_protocol/__init__.py
index 5133682355..e72adaf165 100644
--- a/tests/data/generator/t_protocol/__init__.py
+++ b/tests/data/generator/t_protocol/__init__.py
@@ -20,7 +20,7 @@
"""
This module contains the support resources for the t_protocol protocol.
-It was created with protocol buffer compiler version `libprotoc 3.11.4` and aea version `1.0.0`.
+It was created with protocol buffer compiler version `libprotoc 3.11.4` and aea version `1.0.1`.
"""
from tests.data.generator.t_protocol.message import TProtocolMessage
diff --git a/tests/data/generator/t_protocol/protocol.yaml b/tests/data/generator/t_protocol/protocol.yaml
index bba77a073d..fa8e8b32f2 100644
--- a/tests/data/generator/t_protocol/protocol.yaml
+++ b/tests/data/generator/t_protocol/protocol.yaml
@@ -7,7 +7,7 @@ description: A protocol for testing purposes.
license: Apache-2.0
aea_version: '>=1.0.0, <2.0.0'
fingerprint:
- __init__.py: QmXXHNCXajz8QcHirDJbeFB1sz9ncWrTsbsQydvKV51EUB
+ __init__.py: QmRFM25tWb2wzG4KsJjMQUiWBVq2Sv4x1U9bMtz7j14Mqh
custom_types.py: QmWg8HFav8w9tfZfMrTG5Uo7QpexvYKKkhpGPD18233pLw
dialogues.py: QmWAdikDRJWTG7HUXsCsZRg4Wxnf8cMr5KujpyC4M75gnB
message.py: QmTjeJythfhy4XyzXRCA4fY2eULHciHBRCowWpZkEH77z9
diff --git a/tests/data/generator/t_protocol_no_ct/__init__.py b/tests/data/generator/t_protocol_no_ct/__init__.py
index 856225bc44..b47c9a013d 100644
--- a/tests/data/generator/t_protocol_no_ct/__init__.py
+++ b/tests/data/generator/t_protocol_no_ct/__init__.py
@@ -20,7 +20,7 @@
"""
This module contains the support resources for the t_protocol_no_ct protocol.
-It was created with protocol buffer compiler version `libprotoc 3.11.4` and aea version `1.0.0`.
+It was created with protocol buffer compiler version `libprotoc 3.11.4` and aea version `1.0.1`.
"""
from tests.data.generator.t_protocol_no_ct.message import TProtocolNoCtMessage
diff --git a/tests/data/generator/t_protocol_no_ct/protocol.yaml b/tests/data/generator/t_protocol_no_ct/protocol.yaml
index bd03b9cc8d..cb4d6420c9 100644
--- a/tests/data/generator/t_protocol_no_ct/protocol.yaml
+++ b/tests/data/generator/t_protocol_no_ct/protocol.yaml
@@ -7,7 +7,7 @@ description: A protocol for testing purposes.
license: Apache-2.0
aea_version: '>=1.0.0, <2.0.0'
fingerprint:
- __init__.py: QmYqGhtZRqrk3d6Sjvu3GGq1JqURkhcEdS8jwqhBTDkdQv
+ __init__.py: QmP56cVMkxKriXjZYRsjrN5NY1qPo9xdCQjhm5oBvXePN3
dialogues.py: Qmeq7m8vf1LW5WeehNG8qnoGoRstQrABw2vdQh5tmB3KxX
message.py: QmWBJxk69r34YiRTpadyd6JbKxMEBGj8zwnpZsj6r2Wg5d
serialization.py: QmSGoA2WjKU7F6oYfLwxG4uJVFuVhHNRSo7TNJ1EuYadEg
From 3e3be447ae8cc50acd6999cc0a99c3f7781ed4c7 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 23:06:29 +0200
Subject: [PATCH 047/147] reintroduce check_all_protocols in CI
---
.github/workflows/workflow.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml
index db1d24562e..dd76f4ad34 100644
--- a/.github/workflows/workflow.yml
+++ b/.github/workflows/workflow.yml
@@ -149,8 +149,8 @@ jobs:
run: tox -e package_version_checks
- name: Check package dependencies
run: tox -e package_dependencies_checks
- # - name: Check generate protocols
- # run: tox -e check_generate_all_protocols
+ - name: Check generate protocols
+ run: tox -e check_generate_all_protocols
- name: Generate Documentation
run: tox -e docs
From 7626d9ee3deb171fbea4fdf82589e80c7cae3ae5 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 23:23:17 +0200
Subject: [PATCH 048/147] add --no-bump to check_generate_all_protocols in
tox.ini
---
.github/workflows/workflow.yml | 4 ++--
tox.ini | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml
index dd76f4ad34..f51aeb8aef 100644
--- a/.github/workflows/workflow.yml
+++ b/.github/workflows/workflow.yml
@@ -149,8 +149,8 @@ jobs:
run: tox -e package_version_checks
- name: Check package dependencies
run: tox -e package_dependencies_checks
- - name: Check generate protocols
- run: tox -e check_generate_all_protocols
+ - name: Check generate protocols
+ run: tox -e check_generate_all_protocols
- name: Generate Documentation
run: tox -e docs
diff --git a/tox.ini b/tox.ini
index 4bd94462a6..3483ed172c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -294,7 +294,7 @@ deps =
ipfshttpclient==0.6.1
black==19.10b0
isort==5.7.0
-commands = {toxinidir}/scripts/generate_all_protocols.py --check-clean
+commands = {toxinidir}/scripts/generate_all_protocols.py --no-bump --check-clean
[testenv:spell_check]
skipsdist = True
From 7433548a505e9322ff9253cbda95b91e5b9cf3d8 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 23:40:15 +0200
Subject: [PATCH 049/147] put upperbound to 'click' <8.0.0
---
setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/setup.py b/setup.py
index 509f8bcd83..17347d6402 100644
--- a/setup.py
+++ b/setup.py
@@ -30,7 +30,7 @@
def get_all_extras() -> Dict:
cli_deps = [
- "click",
+ "click<8.0.0",
"pyyaml>=4.2b1",
"jsonschema>=3.0.0",
"packaging>=20.3",
From 449db3d32dd07173d57939601c74b06b2f7ba6af Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 11 May 2021 23:55:11 +0200
Subject: [PATCH 050/147] update test aea package hashes
---
tests/data/hashes.csv | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/data/hashes.csv b/tests/data/hashes.csv
index a4eaac9895..4c642dd06a 100644
--- a/tests/data/hashes.csv
+++ b/tests/data/hashes.csv
@@ -2,7 +2,7 @@ dummy_author/agents/dummy_aea,QmVmz9HDijBdNmTmkCqCBBYkEviwcLj7ib37qSguvP25EN
dummy_author/skills/dummy_skill,QmXHU1KwFNtJWrXv9TUqE1dLWwumky2HFuGKohGiD4HKiP
fetchai/connections/dummy_connection,QmTLkQHXmZd8xF46Ds47pyTUuLQuosC4PNwh9waxtzQv1b
fetchai/contracts/dummy_contract,QmP67brp7EU1kg6n2ckQP6A6jfxLJDeCBD5J6EzpDGb5Kb
-fetchai/protocols/t_protocol,QmQPdqsTrRxwXEPDBd9whn49aEWLKeyxg68pH31xFR7ME9
-fetchai/protocols/t_protocol_no_ct,QmU16WJ38M9rorGR9M4inHh5iVpy1btv38cy8cbbPwP33J
+fetchai/protocols/t_protocol,QmNqV6QvRuBrfXbNgqKhU9BWZ83Tz1CegbhXT8anf8RiQE
+fetchai/protocols/t_protocol_no_ct,QmfNEK4uVktCWNmBzsb9xzsd256NdKADSH3hnJNqeKPJE9
fetchai/skills/dependencies_skill,QmaxnwbY9u3JPYfc2gnmiCjFd9mCfgXV8Yv5B9VbsDkg7K
fetchai/skills/exception_skill,Qmcch6VUH2YELniNiaJxLNa19BRD8PAzb5HTzd7SQhEBgf
From 1f27ebafbea75c6dd2fe92e4aadc4cf835103740 Mon Sep 17 00:00:00 2001
From: "Yuri (solarw) Turchenkov"
Date: Wed, 12 May 2021 13:16:36 +0300
Subject: [PATCH 051/147] fix click package version
---
setup.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/setup.py b/setup.py
index 509f8bcd83..378147e257 100644
--- a/setup.py
+++ b/setup.py
@@ -30,7 +30,7 @@
def get_all_extras() -> Dict:
cli_deps = [
- "click",
+ "click>=7.1.2,<8.0.0",
"pyyaml>=4.2b1",
"jsonschema>=3.0.0",
"packaging>=20.3",
From 513f8fc49457e499f7fc5cba05240b208e0e0b81 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Wed, 12 May 2021 12:45:14 +0100
Subject: [PATCH 052/147] feat: bound version of dependencies by next major
---
plugins/aea-cli-ipfs/setup.py | 2 +-
plugins/aea-ledger-cosmos/setup.py | 4 ++--
plugins/aea-ledger-fetchai/setup.py | 4 ++--
setup.py | 24 ++++++++++++------------
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/plugins/aea-cli-ipfs/setup.py b/plugins/aea-cli-ipfs/setup.py
index e54cb86146..7f9877ffeb 100755
--- a/plugins/aea-cli-ipfs/setup.py
+++ b/plugins/aea-cli-ipfs/setup.py
@@ -33,7 +33,7 @@
description="CLI extension for AEA framework wrapping IPFS functionality.",
packages=["aea_cli_ipfs"],
entry_points={"aea.cli": ["ipfs_cli_command = aea_cli_ipfs.core:ipfs"]},
- install_requires=["aea>=1.0.0, <2.0.0", "ipfshttpclient>=0.6.1"],
+ install_requires=["aea>=1.0.0, <2.0.0", "ipfshttpclient>=0.6.1,<0.8.0"],
classifiers=[
"Environment :: Console",
"Environment :: Web Environment",
diff --git a/plugins/aea-ledger-cosmos/setup.py b/plugins/aea-ledger-cosmos/setup.py
index 6ce87d0fce..937c179a06 100644
--- a/plugins/aea-ledger-cosmos/setup.py
+++ b/plugins/aea-ledger-cosmos/setup.py
@@ -32,9 +32,9 @@
packages=find_packages(include=["aea_ledger_cosmos*"]),
install_requires=[
"aea>=1.0.0, <2.0.0",
- "ecdsa>=0.15",
+ "ecdsa>=0.15,<0.17.0",
"bech32==1.2.0",
- "pycryptodome>=3.10.1",
+ "pycryptodome>=3.10.1,<4.0.0",
],
tests_require=["pytest"],
entry_points={
diff --git a/plugins/aea-ledger-fetchai/setup.py b/plugins/aea-ledger-fetchai/setup.py
index fdb7a83d9c..a4c69fd6a8 100644
--- a/plugins/aea-ledger-fetchai/setup.py
+++ b/plugins/aea-ledger-fetchai/setup.py
@@ -37,9 +37,9 @@
packages=find_packages(include=["aea_ledger_fetchai*"]),
install_requires=[
"aea>=1.0.0, <2.0.0",
- "ecdsa>=0.15",
+ "ecdsa>=0.15,<0.17.0",
"bech32==1.2.0",
- "pycryptodome>=3.10.1",
+ "pycryptodome>=3.10.1,<4.0.0",
],
tests_require=["pytest"],
entry_points={
diff --git a/setup.py b/setup.py
index 17347d6402..45b39f4de2 100644
--- a/setup.py
+++ b/setup.py
@@ -30,10 +30,10 @@
def get_all_extras() -> Dict:
cli_deps = [
- "click<8.0.0",
- "pyyaml>=4.2b1",
- "jsonschema>=3.0.0",
- "packaging>=20.3",
+ "click>=7.0.0,<8.0.0",
+ "pyyaml>=4.2b1,<6.0",
+ "jsonschema>=3.0.0,<4.0.0",
+ "packaging>=20.3,<21.0",
]
extras = {
@@ -49,16 +49,16 @@ def get_all_extras() -> Dict:
all_extras = get_all_extras()
base_deps = [
- "base58>=1.0.3",
- "jsonschema>=3.0.0",
- "packaging>=20.3",
- "semver>=2.9.1",
+ "base58>=1.0.3,<3.0.0",
+ "jsonschema>=3.0.0,<4.0.0",
+ "packaging>=20.3,<21.0",
+ "semver>=2.9.1,<3.0.0",
"protobuf==3.13.0",
"pymultihash==0.8.2",
- "pyyaml>=4.2b1",
- "requests>=2.22.0",
- "python-dotenv>=0.14.0",
- "ecdsa>=0.15"
+ "pyyaml>=4.2b1,<6.0",
+ "requests>=2.22.0,<3.0.0",
+ "python-dotenv>=0.14.0,<0.18.0",
+ "ecdsa>=0.15,<0.17.0"
]
if os.name == "nt" or os.getenv("WIN_BUILD_WHEEL", None) == "1":
From adbaa81881125f76719c6ef42990b04db161770a Mon Sep 17 00:00:00 2001
From: ali
Date: Wed, 12 May 2021 17:59:54 +0100
Subject: [PATCH 053/147] docs: update with aea manager instructions
carpark;ml;thermometer;weather
---
docs/car-park-skills.md | 28 ++++++++--------
docs/ml-skills.md | 43 ++++++++++++------------
docs/thermometer-skills.md | 68 ++++++++++++++++++++++++++++++--------
docs/weather-skills.md | 63 +++++++++++++++++++++++++++++------
4 files changed, 144 insertions(+), 58 deletions(-)
diff --git a/docs/car-park-skills.md b/docs/car-park-skills.md
index 52410c5d79..618711b99c 100644
--- a/docs/car-park-skills.md
+++ b/docs/car-park-skills.md
@@ -45,15 +45,15 @@ This diagram shows the communication between the various entities as data is suc
-# Option 1: AEA Manager approach
+## Option 1: AEA Manager approach
Follow this approach when using the AEA Manager Desktop app. Otherwise, skip and follow the CLI approach below.
-## Preparation instructions
+### Preparation instructions
Install the AEA Manager.
-## Demo instructions
+### Demo instructions
The following steps assume you have launched the AEA Manager Desktop app.
@@ -65,7 +65,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `car_detector` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `car_data_buyer` and update as follows:
+5. Navigate to the settings of the `car_data_buyer` and under `connections/fetchai/p2p_libp2p:0.22.0` update as follows:
``` bash
{
"delegate_uri": "127.0.0.1:11001",
@@ -81,19 +81,19 @@ The following steps assume you have launched the AEA Manager Desktop app.
In the AEA's logs should see the agent trading successfully.
-# Option 2: CLI approach
+## Option 2: CLI approach
Follow this approach when using the `aea` CLI.
-## Preparation instructions
+### Preparation instructions
-### Dependencies
+#### Dependencies
Follow the Preliminaries and Installation sections from the AEA quick start.
-## Demo instructions
+### Demo instructions
-### Create car detector AEA
+#### Create car detector AEA
First, fetch the car detector AEA:
``` bash
@@ -131,7 +131,7 @@ aea build
-### Create car data buyer AEA
+#### Create car data buyer AEA
Then, fetch the car data client AEA:
``` bash
@@ -170,7 +170,7 @@ aea build
-### Add keys for the car data seller AEA
+#### Add keys for the car data seller AEA
First, create the private key for the car data seller AEA based on the network you want to transact. To generate and add a private-public key pair for Fetch.ai `AgentLand` use:
``` bash
@@ -189,7 +189,7 @@ Finally, certify the key for use by the connections that request that:
aea issue-certificates
```
-### Add keys and generate wealth for the car data buyer AEA
+#### Add keys and generate wealth for the car data buyer AEA
The buyer needs to have some wealth to purchase the service from the seller.
@@ -215,7 +215,7 @@ Finally, certify the key for use by the connections that request that:
aea issue-certificates
```
-## Run the AEAs
+### Run the AEAs
Run both AEAs from their respective terminals.
@@ -248,7 +248,7 @@ aea run
You will see that the AEAs negotiate and then transact using the Fetch.ai testnet.
-### Cleaning up
+#### Cleaning up
When you're finished, delete your AEAs:
``` bash
diff --git a/docs/ml-skills.md b/docs/ml-skills.md
index 65b3c16357..dc06c4fdc3 100644
--- a/docs/ml-skills.md
+++ b/docs/ml-skills.md
@@ -1,18 +1,18 @@
-The AEA ML (machine learning) skills demonstrate an interaction between two AEAs trading data.
+The AEA ML (machine learning) skills demonstrate an interaction between two AEAs, one purchasing data from the other and training a machine learning model with it.
There are two types of AEAs:
* The `ml_data_provider` which sells training data.
-* The `ml_model_trainer` which trains a model
+* The `ml_model_trainer` which purchases data and trains a model
## Discussion
-The scope of the specific demo is to demonstrate how to create a simple AEA with integration of machine learning, and the usage of the AEA framework. The `ml_data_provider` AEA
-will provide some sample data and will deliver to the client upon payment. Once the client gets the data, it will train the model. The process can be found in the `tasks.py` file.
-This demo does not utilize a smart contract. As a result, we interact with a ledger only to complete a transaction.
+This demo aims to demonstrate the integration of a simple AEA with machine learning using the AEA framework. The `ml_data_provider` AEA provides some sample data and delivers to the client upon payment.
+Once the client receives the data, it trains a model. This process can be found in `tasks.py`.
+This demo does not utilize a smart contract. As a result, the ledger interaction is only for completing a transaction.
-Since the AEA framework enables us to use third-party libraries hosted on PyPI we can directly reference the external dependencies.
-The `aea install` command will install each dependency that the specific AEA needs and is listed in the skill's YAML file.
+Since the AEA framework enables using third-party libraries from PyPI, we can directly reference any external dependencies.
+The `aea install` command installs all dependencies an AEA needs that is listed in one of its skills' YAML file.
## Communication
@@ -48,17 +48,18 @@ This diagram shows the communication between the two AEAs.
deactivate Search
deactivate Ledger
-
+
+
-# Option 1: AEA Manager approach
+## Option 1: AEA Manager approach
Follow this approach when using the AEA Manager Desktop app. Otherwise, skip and follow the CLI approach below.
-## Preparation instructions
+### Preparation instructions
Install the AEA Manager.
-## Demo instructions
+### Demo instructions
The following steps assume you have launched the AEA Manager Desktop app.
@@ -86,19 +87,19 @@ The following steps assume you have launched the AEA Manager Desktop app.
In the AEA's logs should see the agent trading successfully.
-# Option 2: CLI approach
+## Option 2: CLI approach
Follow this approach when using the `aea` CLI.
-## Preparation instructions
+### Preparation instructions
-### Dependencies
+#### Dependencies
Follow the Preliminaries and Installation sections from the AEA quick start.
-## Demo instructions
+### Demo instructions
-### Create data provider AEA
+#### Create data provider AEA
First, fetch the data provider AEA:
``` bash
@@ -136,7 +137,7 @@ aea build
-### Create model trainer AEA
+#### Create model trainer AEA
Then, fetch the model trainer AEA:
``` bash
@@ -175,7 +176,7 @@ aea build
-### Add keys for the data provider AEA
+#### Add keys for the data provider AEA
First, create the private key for the data provider AEA based on the network you want to transact. To generate and add a private-public key pair for Fetch.ai `AgentLand` use:
``` bash
@@ -194,7 +195,7 @@ Finally, certify the key for use by the connections that request that:
aea issue-certificates
```
-### Add keys and generate wealth for the model trainer AEA
+#### Add keys and generate wealth for the model trainer AEA
The model trainer needs to have some wealth to purchase the data from the data provider.
@@ -220,7 +221,7 @@ Finally, certify the key for use by the connections that request that:
aea issue-certificates
```
-### Run both AEAs
+#### Run both AEAs
Run both AEAs from their respective terminals.
@@ -272,7 +273,7 @@ aea run
You can see that the AEAs find each other, negotiate and eventually trade.
-### Cleaning up
+#### Cleaning up
When you're finished, delete your AEAs:
``` bash
diff --git a/docs/thermometer-skills.md b/docs/thermometer-skills.md
index 5e556e1087..0ed2fa9987 100644
--- a/docs/thermometer-skills.md
+++ b/docs/thermometer-skills.md
@@ -1,15 +1,15 @@
-The AEA thermometer skills demonstrate an interaction between two AEAs.
+The AEA thermometer skills demonstrate an interaction between two AEAs, one purchasing temperature data from the other.
* The provider of thermometer data (the `thermometer`).
* The buyer of thermometer data (the `thermometer_client`).
## Discussion
-The scope of the specific demo is to demonstrate how to create a very simple AEA with the usage of the AEA framework and a thermometer sensor. The thermometer AEA will read data from the sensor each time a client requests and will deliver to the client upon payment. To keep the demo simple we avoided the usage of a database since this would increase the complexity. As a result, the AEA can provide only one reading from the sensor. This demo does not utilise a smart contract. As a result, we interact with a ledger only to complete a transaction.
+This demo aims to demonstrate how to create a very simple AEA with the usage of the AEA framework and a thermometer sensor. The thermometer AEA will read data from the sensor each time a client requests the data and will deliver it to the client upon payment. To keep the demo simple, we avoided the usage of a database since this would increase the complexity. As a result, the AEA can provide only one reading from the sensor. This demo does not utilise a smart contract. As a result, the ledger interaction is only for completing a transaction.
## Communication
-This diagram shows the communication between the various entities as data is successfully sold by the thermometer AEA to the client.
+This diagram shows the communication between the various entities as data is successfully sold by the thermometer AEA to the client AEA.
sequenceDiagram
@@ -41,18 +41,59 @@ This diagram shows the communication between the various entities as data is suc
deactivate Blockchain
+
-## Preparation instructions
+## Option 1: AEA Manager approach
+
+Follow this approach when using the AEA Manager Desktop app. Otherwise, skip and follow the CLI approach below.
+
+### Preparation instructions
+
+Install the AEA Manager.
+
+### Demo instructions
+
+The following steps assume you have launched the AEA Manager Desktop app.
+
+1. Add a new AEA called `my_thermometer_aea` with public id `fetchai/thermometer_aea:0.27.0`.
+
+2. Add another new AEA called `my_thermometer_client` with public id `fetchai/thermometer_client:0.28.0`.
+
+3. Copy the address from the `my_thermometer_client` into your clip board. Then go to the AgentLand block explorer and request some test tokens via `Get Funds`.
+
+4. Run the `my_thermometer_aea` AEA. Navigate to its logs and copy the multiaddress displayed.
+
+5. Navigate to the settings of the `my_thermometer_client` and under `connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+``` bash
+{
+ "delegate_uri": "127.0.0.1:11001",
+ "entry_peers": ["REPLACE_WITH_MULTI_ADDRESS_HERE"],
+ "local_uri": "127.0.0.1:9001",
+ "log_file": "libp2p_node.log",
+ "public_uri": "127.0.0.1:9001"
+}
+```
+
+6. Run the `my_thermometer_client`.
+
+In the AEA's logs should see the agent trading successfully.
+
+
+## Option 2: CLI approach
+
+Follow this approach when using the `aea` CLI.
+
+### Preparation instructions
-### Dependencies
+#### Dependencies
Follow the Preliminaries and Installation sections from the AEA quick start.
-## Demo instructions
+### Demo instructions
A demo to run the thermometer scenario with a true ledger transaction This demo assumes the buyer trusts the seller AEA to send the data upon successful payment.
-### Create thermometer AEA
+#### Create thermometer AEA
First, fetch the thermometer AEA:
``` bash
@@ -86,7 +127,7 @@ aea config set --type dict agent.default_routing \
-### Create thermometer client
+#### Create thermometer client
Then, fetch the thermometer client AEA:
``` bash
@@ -120,7 +161,7 @@ aea config set --type dict agent.default_routing \
-### Add keys for the thermometer AEA
+#### Add keys for the thermometer AEA
First, create the private key for the thermometer AEA based on the network you want to transact. To generate and add a private-public key pair for Fetch.ai `AgentLand` use:
``` bash
@@ -139,7 +180,7 @@ Finally, certify the key for use by the connections that request that:
aea issue-certificates
```
-### Add keys and generate wealth for the thermometer client AEA
+#### Add keys and generate wealth for the thermometer client AEA
The thermometer client needs to have some wealth to purchase the thermometer information.
@@ -165,7 +206,7 @@ Finally, certify the key for use by the connections that request that:
aea issue-certificates
```
-### Run both AEAs
+#### Run both AEAs
Run both AEAs from their respective terminals.
@@ -197,9 +238,10 @@ aea run
You can see that the AEAs find each other, negotiate and eventually trade.
-### Cleaning up
+#### Cleaning up
+
+When you're done, go up a level and delete the AEAs.
-When you're finished, delete your AEAs:
``` bash
cd ..
aea delete my_thermometer_aea
diff --git a/docs/weather-skills.md b/docs/weather-skills.md
index 9efb190c21..f9dae23430 100644
--- a/docs/weather-skills.md
+++ b/docs/weather-skills.md
@@ -45,19 +45,60 @@ This diagram shows the communication between the various entities as data is suc
deactivate Blockchain
+
-## Preparation instructions
+## Option 1: AEA Manager approach
-### Dependencies
+Follow this approach when using the AEA Manager Desktop app. Otherwise, skip and follow the CLI approach below.
+
+### Preparation instructions
+
+Install the AEA Manager.
+
+### Demo instructions
+
+The following steps assume you have launched the AEA Manager Desktop app.
+
+1. Add a new AEA called `my_weather_station` with public id `fetchai/weather_station:0.29.0`.
+
+2. Add another new AEA called `my_weather_client` with public id `fetchai/weather_client:0.30.0`.
+
+3. Copy the address from the `my_weather_client` into your clip board. Then go to the AgentLand block explorer and request some test tokens via `Get Funds`.
+
+4. Run the `my_weather_station` AEA. Navigate to its logs and copy the multiaddress displayed.
+
+5. Navigate to the settings of the `my_weather_client` and under `connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+``` bash
+{
+ "delegate_uri": "127.0.0.1:11001",
+ "entry_peers": ["REPLACE_WITH_MULTI_ADDRESS_HERE"],
+ "local_uri": "127.0.0.1:9001",
+ "log_file": "libp2p_node.log",
+ "public_uri": "127.0.0.1:9001"
+}
+```
+
+6. Run the `my_weather_client`.
+
+In the AEA's logs should see the agent trading successfully.
+
+
+## Option 2: CLI approach
+
+Follow this approach when using the `aea` CLI.
+
+### Preparation instructions
+
+#### Dependencies
Follow the Preliminaries and Installation sections from the AEA quick start.
-## Demo instructions:
+### Demo instructions:
A demo to run the same scenario but with a true ledger transaction on Fetch.ai `testnet` or Ethereum `ropsten` network. This demo assumes the buyer
trusts the seller AEA to send the data upon successful payment.
-### Create the weather station
+#### Create the weather station
First, fetch the AEA that will provide weather measurements:
``` bash
@@ -96,7 +137,7 @@ aea build
-### Create the weather client
+#### Create the weather client
In another terminal, fetch the AEA that will query the weather station:
``` bash
@@ -135,7 +176,7 @@ aea build
-### Add keys for the weather station AEA
+#### Add keys for the weather station AEA
First, create the private key for the weather station AEA based on the network you want to transact. To generate and add a private-public key pair for Fetch.ai `AgentLand` use:
``` bash
@@ -154,7 +195,7 @@ Finally, certify the key for use by the connections that request that:
aea issue-certificates
```
-### Add keys and generate wealth for the weather client AEA
+#### Add keys and generate wealth for the weather client AEA
The weather client needs to have some wealth to purchase the service from the weather station.
@@ -180,7 +221,7 @@ Finally, certify the key for use by the connections that request that:
aea issue-certificates
```
-### Run the AEAs
+#### Run the AEAs
Run both AEAs from their respective terminals.
@@ -212,7 +253,7 @@ aea run
You will see that the AEAs negotiate and then transact using the selected ledger.
-### Delete the AEAs
+#### Cleaning up
When you're done, go up a level and delete the AEAs.
@@ -220,4 +261,6 @@ When you're done, go up a level and delete the AEAs.
cd ..
aea delete my_weather_station
aea delete my_weather_client
-```
\ No newline at end of file
+```
+
+
\ No newline at end of file
From f65d7a19553b1d1a0089d8ff1c670dc12268c055 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Sat, 15 May 2021 11:59:09 +0200
Subject: [PATCH 054/147] feat: update bump_aea_version script.
- add '--only-check' flag to only check the need for bumping (but no bumping)
- slighly refactor code to switch between the two modes
---
scripts/bump_aea_version.py | 150 +++++++++++++++++++++++++++---------
1 file changed, 113 insertions(+), 37 deletions(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index 90a39d0ef8..c95654fc14 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -382,7 +382,7 @@ def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser("bump_aea_version")
parser.add_argument(
- "--new-version", type=str, required=True, help="The new AEA version."
+ "--new-version", type=str, required=False, help="The new AEA version."
)
parser.add_argument(
"-p",
@@ -392,11 +392,52 @@ def parse_args() -> argparse.Namespace:
help="Set a number of key-value pairs plugin-name=new-plugin-version",
default={},
)
- parser.add_argument("--no-fingerprints", action="store_true")
+ parser.add_argument(
+ "--no-fingerprints",
+ action="store_true",
+ help="Skip the recomputation of fingerprints.",
+ )
+ parser.add_argument(
+ "--only-check", action="store_true", help="Only check the need of upgrade."
+ )
arguments_ = parser.parse_args()
return arguments_
+def make_aea_bumper(new_aea_version: Version) -> PythonPackageVersionBumper:
+ """Build the AEA Python package version bumper."""
+ aea_version_bumper = PythonPackageVersionBumper(
+ ROOT_DIR,
+ AEA_DIR,
+ new_aea_version,
+ specifier_set_patterns=[
+ "(?<=aea_version:) *({specifier_set})",
+ "(?<={package_name})({specifier_set})",
+ ],
+ files_to_pattern=AEA_PATHS,
+ )
+ return aea_version_bumper
+
+
+def make_plugin_bumper(
+ plugin_dir: Path, new_version: Version
+) -> PythonPackageVersionBumper:
+ """Build the plugin Python package version bumper."""
+ plugin_package_dir = plugin_dir / plugin_dir.name.replace("-", "_")
+ plugin_version_bumper = PythonPackageVersionBumper(
+ ROOT_DIR,
+ plugin_package_dir,
+ new_version,
+ files_to_pattern={},
+ specifier_set_patterns=[
+ YAML_DEPENDENCY_SPECIFIER_SET_PATTERN,
+ JSON_DEPENDENCY_SPECIFIER_SET_PATTERN,
+ ],
+ package_name=plugin_dir.name,
+ )
+ return plugin_version_bumper
+
+
def process_plugins(new_versions: Dict[str, Version]) -> bool:
"""Process plugins."""
result = False
@@ -411,18 +452,7 @@ def process_plugins(new_versions: Dict[str, Version]) -> bool:
logging.info(
f"Processing {plugin_dir_name}: upgrading at version {new_version}"
)
- plugin_package_dir = plugin_dir / plugin_dir.name.replace("-", "_")
- plugin_bumper = PythonPackageVersionBumper(
- ROOT_DIR,
- plugin_package_dir,
- new_version,
- files_to_pattern={},
- specifier_set_patterns=[
- YAML_DEPENDENCY_SPECIFIER_SET_PATTERN,
- JSON_DEPENDENCY_SPECIFIER_SET_PATTERN,
- ],
- package_name=plugin_dir.name,
- )
+ plugin_bumper = make_plugin_bumper(plugin_dir, new_version)
plugin_bumper.run()
result |= plugin_bumper.result
return result
@@ -438,33 +468,58 @@ def parse_plugin_versions(key_value_strings: List[str]) -> Dict[str, Version]:
}
-if __name__ == "__main__":
- arguments = parse_args()
+def only_check_bump_needed() -> int:
+ """
+ Check whether a version bump is needed for AEA and plugins.
+
+ :return: the return code
+ """
+ bumpers: List[PythonPackageVersionBumper] = list()
+ to_upgrade: List[Path] = list()
+ bumpers.append(make_aea_bumper(None)) # type: ignore
+ for plugin_dir in ALL_PLUGINS:
+ bumpers.append(make_plugin_bumper(plugin_dir, None)) # type: ignore
+
+ latest_tag = str(bumpers[0].repo.tags[-1])
+ logging.info(
+ f"Checking packages that have changes from tag {latest_tag} and that require a new release..."
+ )
+ for bumper in bumpers:
+ if bumper.is_different_from_latest_tag():
+ logging.info(
+ f"Package {bumper.python_pkg_dir} is different from latest tag {latest_tag}."
+ )
+ to_upgrade.append(bumper.python_pkg_dir)
+
+ if len(to_upgrade) > 0:
+ logging.info("Packages to upgrade:")
+ for path in to_upgrade:
+ logging.info(path)
+ else:
+ logging.info("No packages to upgrade.")
+ return 0
+
+
+def bump(arguments: argparse.Namespace) -> int:
+ """
+ Bump versions.
+
+ :param arguments: arguments from argparse
+ :return: the return code
+ """
new_plugin_versions = parse_plugin_versions(arguments.plugin_new_version)
logging.info(f"Parsed arguments: {arguments}")
logging.info(f"Parsed plugin versions: {new_plugin_versions}")
- repo = Repo(str(ROOT_DIR))
- if repo.is_dirty():
- logging.info(
- "Repository is dirty. Please clean it up before running this script."
- )
- sys.exit(1)
-
- new_aea_version = Version(arguments.new_version)
- aea_version_bumper = PythonPackageVersionBumper(
- ROOT_DIR,
- AEA_DIR,
- new_aea_version,
- specifier_set_patterns=[
- "(?<=aea_version:) *({specifier_set})",
- "(?<={package_name})({specifier_set})",
- ],
- files_to_pattern=AEA_PATHS,
- )
- aea_version_bumper.run()
- have_updated_specifier_set = aea_version_bumper.result
- logging.info("AEA package processed.")
+ have_updated_specifier_set = False
+ if arguments.new_version is not None:
+ new_aea_version = Version(arguments.new_version)
+ aea_version_bumper = make_aea_bumper(new_aea_version)
+ aea_version_bumper.run()
+ have_updated_specifier_set = aea_version_bumper.result
+ logging.info("AEA package processed.")
+ else:
+ logging.info("AEA package not processed - no version provided.")
logging.info("Processing plugins:")
have_updated_specifier_set |= process_plugins(new_plugin_versions)
@@ -482,4 +537,25 @@ def parse_plugin_versions(key_value_strings: List[str]) -> Dict[str, Version]:
else:
logging.info("Updating hashes and fingerprints.")
return_code = update_hashes()
+ return return_code
+
+
+def main() -> None:
+ """Run the script."""
+ repo = Repo(str(ROOT_DIR))
+ if repo.is_dirty():
+ logging.info(
+ "Repository is dirty. Please clean it up before running this script."
+ )
+ sys.exit(1)
+
+ arguments = parse_args()
+ if arguments.only_check:
+ sys.exit(only_check_bump_needed())
+
+ return_code = bump(arguments)
sys.exit(return_code)
+
+
+if __name__ == "__main__":
+ main()
From 81104fdd8be70e56ad787d581b8c375fe84405f7 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Sat, 15 May 2021 12:12:10 +0200
Subject: [PATCH 055/147] improve 'git diff' info log message
---
scripts/bump_aea_version.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index c95654fc14..44ed1e8d9c 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -372,7 +372,7 @@ def is_different_from_latest_tag(self) -> bool:
assert len(self.repo.tags) > 0, "no git tags found"
latest_tag_str = str(self.repo.tags[-1])
args = latest_tag_str, "--", str(self.python_pkg_dir)
- logging.info(f"Running 'git diff with args: {args}'")
+ logging.info(f"Running 'git diff {' '.join(args)}'")
diff = self.repo.git.diff(*args)
return diff != ""
From 538c1ab22c44c9562f38fd666a65f10cd5ec6814 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Sat, 15 May 2021 14:20:57 +0200
Subject: [PATCH 056/147] update docstring of 'scripts/bump_aea_version.py'
---
scripts/bump_aea_version.py | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/scripts/bump_aea_version.py b/scripts/bump_aea_version.py
index 44ed1e8d9c..29e9d6b43c 100644
--- a/scripts/bump_aea_version.py
+++ b/scripts/bump_aea_version.py
@@ -21,8 +21,9 @@
"""
Bump the AEA version throughout the code base.
-usage: bump_aea_version [-h] --new-version NEW_VERSION
+usage: bump_aea_version [-h] [--new-version NEW_VERSION]
[-p KEY=VALUE [KEY=VALUE ...]] [--no-fingerprints]
+ [--only-check]
optional arguments:
-h, --help show this help message and exit
@@ -31,11 +32,14 @@
-p KEY=VALUE [KEY=VALUE ...], --plugin-new-version KEY=VALUE [KEY=VALUE ...]
Set a number of key-value pairs plugin-name=new-
plugin-version
- --no-fingerprints
+ --no-fingerprints Skip the computation of fingerprints.
+ --only-check Only check the need of upgrade.
+
Example of usage:
python scripts/bump_aea_version.py --new-version 1.1.0 -p aea-ledger-fetchai=2.0.0 -p aea-ledger-ethereum=3.0.0
+python scripts/bump_aea_version.py --only-check
"""
import argparse
@@ -395,7 +399,7 @@ def parse_args() -> argparse.Namespace:
parser.add_argument(
"--no-fingerprints",
action="store_true",
- help="Skip the recomputation of fingerprints.",
+ help="Skip the computation of fingerprints.",
)
parser.add_argument(
"--only-check", action="store_true", help="Only check the need of upgrade."
From 189db196a4a77f27ca2de93f43c27a3ad8ee88ba Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 17 May 2021 06:46:00 +0000
Subject: [PATCH 057/147] chore(deps-dev): bump pydoc-markdown from 3.3.0 to
3.10.3
Bumps [pydoc-markdown](https://github.com/NiklasRosenstein/pydoc-markdown) from 3.3.0 to 3.10.3.
- [Release notes](https://github.com/NiklasRosenstein/pydoc-markdown/releases)
- [Commits](https://github.com/NiklasRosenstein/pydoc-markdown/compare/v3.3.0...v3.10.3)
Signed-off-by: dependabot[bot]
---
Pipfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Pipfile b/Pipfile
index e74696761a..a9bf947d1b 100644
--- a/Pipfile
+++ b/Pipfile
@@ -45,7 +45,7 @@ packaging = "==20.4"
pexpect = "==4.8.0"
psutil = "==5.7.0"
pycryptodome = ">=3.10.1"
-pydoc-markdown = "==3.3.0"
+pydoc-markdown = "==3.10.3"
pydocstyle = "==3.0.0"
pygments = "==2.7.4"
pylint = "==2.6.0"
From f81d7546da4a220593b5674ecef41166902a8c1e Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Mon, 17 May 2021 10:31:23 +0100
Subject: [PATCH 058/147] chore: update tox.ini deps for pydoc too
---
tox.ini | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tox.ini b/tox.ini
index 3483ed172c..d874576c00 100644
--- a/tox.ini
+++ b/tox.ini
@@ -284,7 +284,7 @@ commands = {toxinidir}/scripts/check_doc_links.py
skipsdist = True
usedevelop = True
deps =
- pydoc-markdown==3.3.0
+ pydoc-markdown==3.10.3
commands = {toxinidir}/scripts/generate_api_docs.py --check-clean
[testenv:check_generate_all_protocols]
From 1aadb4f6d8dbc79f9ba2f2e2b6c5f23f7c6a23a6 Mon Sep 17 00:00:00 2001
From: ali
Date: Mon, 17 May 2021 12:35:33 +0100
Subject: [PATCH 059/147] docs: add manager to tac demo + cleanup
---
docs/car-park-skills.md | 2 +-
docs/ml-skills.md | 2 +-
docs/tac-skills.md | 54 ++++++++++++++++++++++++++++++++++++++
docs/thermometer-skills.md | 2 +-
docs/weather-skills.md | 2 +-
5 files changed, 58 insertions(+), 4 deletions(-)
diff --git a/docs/car-park-skills.md b/docs/car-park-skills.md
index 618711b99c..1b70bea8ec 100644
--- a/docs/car-park-skills.md
+++ b/docs/car-park-skills.md
@@ -65,7 +65,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `car_detector` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `car_data_buyer` and under `connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+5. Navigate to the settings of the `car_data_buyer` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
``` bash
{
"delegate_uri": "127.0.0.1:11001",
diff --git a/docs/ml-skills.md b/docs/ml-skills.md
index dc06c4fdc3..f58d1314cc 100644
--- a/docs/ml-skills.md
+++ b/docs/ml-skills.md
@@ -71,7 +71,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `ml_data_provider` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `car_data_buyer` and under `connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+5. Navigate to the settings of the `ml_model_trainer` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
``` bash
{
"delegate_uri": "127.0.0.1:11001",
diff --git a/docs/tac-skills.md b/docs/tac-skills.md
index f4310a52c5..b4816037f9 100644
--- a/docs/tac-skills.md
+++ b/docs/tac-skills.md
@@ -87,6 +87,60 @@ In the above case, the proposal received contains a set of good which the seller
There is an equivalent diagram for seller AEAs set up to search for buyers and their interaction with AEAs which are registered as buyers. In that scenario, the proposal will instead, be a list of goods that the buyer wishes to buy and the price it is willing to pay for them.
+## Option 1: AEA Manager approach
+
+Follow this approach when using the AEA Manager Desktop app. Otherwise, skip and follow the CLI approach below.
+
+### Preparation instructions
+
+Install the AEA Manager.
+
+### Demo instructions
+
+The following steps assume you have launched the AEA Manager Desktop app.
+
+1. Add a new AEA called `controller` with public id `fetchai/tac_controller:0.26.0`.
+
+2. Add another new AEA called `participant_1` with public id `fetchai/tac_participant:0.28.0`.
+
+3. Add another new AEA called `participant_2` with public id `fetchai/tac_participant:0.28.0`.
+
+4. Navigate to the settings of `controller` and under `components > skills/fetchai/tac_controller:0.22.0 > models > parameters > args` update `registration_start_time` to the time you want TAC to begin (e.g. 2 minutes in the future)
+
+5. Run the `controller` AEA. Navigate to its logs and copy the multiaddress displayed. Stop the `controller`.
+
+5. Navigate to the settings of `participant_1` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+``` bash
+{
+ "delegate_uri": "127.0.0.1:11001",
+ "entry_peers": ["REPLACE_WITH_MULTI_ADDRESS_HERE"],
+ "local_uri": "127.0.0.1:9001",
+ "log_file": "libp2p_node.log",
+ "public_uri": "127.0.0.1:9001"
+}
+```
+
+6. Navigate to the settings of `participant_2` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+``` bash
+{
+ "delegate_uri": "127.0.0.1:11002",
+ "entry_peers": ["REPLACE_WITH_MULTI_ADDRESS_HERE"],
+ "local_uri": "127.0.0.1:9002",
+ "log_file": "libp2p_node.log",
+ "public_uri": "127.0.0.1:9002"
+}
+```
+
+7. You may add more participants by repeating steps 3 (with an updated name) and 6 (bumping the port numbers. See the difference between steps 5 and 6).
+
+8. Run the `controller`, then `participant_1` and `participant_2` (and any other participants you added).
+
+In the `controller`'s log, you should see the details of the transactions participants submit as well as changes in their scores and holdings. In participants' logs, you should see the agents trading.
+
+
+## Option 2: CLI approach
+
+Follow this approach when using the `aea` CLI.
## Preparation instructions
diff --git a/docs/thermometer-skills.md b/docs/thermometer-skills.md
index 0ed2fa9987..4a3e908e80 100644
--- a/docs/thermometer-skills.md
+++ b/docs/thermometer-skills.md
@@ -63,7 +63,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `my_thermometer_aea` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `my_thermometer_client` and under `connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+5. Navigate to the settings of the `my_thermometer_client` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
``` bash
{
"delegate_uri": "127.0.0.1:11001",
diff --git a/docs/weather-skills.md b/docs/weather-skills.md
index f9dae23430..fa4c5cf793 100644
--- a/docs/weather-skills.md
+++ b/docs/weather-skills.md
@@ -67,7 +67,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `my_weather_station` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `my_weather_client` and under `connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+5. Navigate to the settings of the `my_weather_client` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
``` bash
{
"delegate_uri": "127.0.0.1:11001",
From 5b387d5c2a2bd88eda7bfce81fefa6457078e035 Mon Sep 17 00:00:00 2001
From: ali
Date: Mon, 17 May 2021 12:40:40 +0100
Subject: [PATCH 060/147] docs: pr comments
---
docs/car-park-skills.md | 4 ++--
docs/ml-skills.md | 4 ++--
docs/tac-skills.md | 4 ++--
docs/thermometer-skills.md | 4 ++--
docs/weather-skills.md | 4 ++--
5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/docs/car-park-skills.md b/docs/car-park-skills.md
index 1b70bea8ec..e7b248e4ed 100644
--- a/docs/car-park-skills.md
+++ b/docs/car-park-skills.md
@@ -65,7 +65,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `car_detector` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `car_data_buyer` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+5. Navigate to the settings of the `car_data_buyer` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11001",
@@ -78,7 +78,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
6. Run the `car_data_buyer`.
-In the AEA's logs should see the agent trading successfully.
+In the AEA's logs, you should see the agent trading successfully.
## Option 2: CLI approach
diff --git a/docs/ml-skills.md b/docs/ml-skills.md
index f58d1314cc..933dfde84a 100644
--- a/docs/ml-skills.md
+++ b/docs/ml-skills.md
@@ -71,7 +71,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `ml_data_provider` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `ml_model_trainer` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+5. Navigate to the settings of the `ml_model_trainer` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11001",
@@ -84,7 +84,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
6. Run the `ml_model_trainer`.
-In the AEA's logs should see the agent trading successfully.
+In the AEA's logs, you should see the agent trading successfully.
## Option 2: CLI approach
diff --git a/docs/tac-skills.md b/docs/tac-skills.md
index b4816037f9..c58d8f5415 100644
--- a/docs/tac-skills.md
+++ b/docs/tac-skills.md
@@ -109,7 +109,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
5. Run the `controller` AEA. Navigate to its logs and copy the multiaddress displayed. Stop the `controller`.
-5. Navigate to the settings of `participant_1` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+5. Navigate to the settings of `participant_1` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11001",
@@ -120,7 +120,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
}
```
-6. Navigate to the settings of `participant_2` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+6. Navigate to the settings of `participant_2` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11002",
diff --git a/docs/thermometer-skills.md b/docs/thermometer-skills.md
index 4a3e908e80..5db274e192 100644
--- a/docs/thermometer-skills.md
+++ b/docs/thermometer-skills.md
@@ -63,7 +63,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `my_thermometer_aea` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `my_thermometer_client` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+5. Navigate to the settings of the `my_thermometer_client` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11001",
@@ -76,7 +76,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
6. Run the `my_thermometer_client`.
-In the AEA's logs should see the agent trading successfully.
+In the AEA's logs, you should see the agent trading successfully.
## Option 2: CLI approach
diff --git a/docs/weather-skills.md b/docs/weather-skills.md
index fa4c5cf793..8336259a12 100644
--- a/docs/weather-skills.md
+++ b/docs/weather-skills.md
@@ -67,7 +67,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `my_weather_station` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `my_weather_client` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows:
+5. Navigate to the settings of the `my_weather_client` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11001",
@@ -80,7 +80,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
6. Run the `my_weather_client`.
-In the AEA's logs should see the agent trading successfully.
+In the AEA's logs, you should see the agent trading successfully.
## Option 2: CLI approach
From 2cd993eae0fab3a59ac75fcbab4d1963f92868d2 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 17 May 2021 14:15:05 +0200
Subject: [PATCH 061/147] update aea.skills.base.py on skill loading
Fix 'not declared in configuration file' warning for 'tac_controller_contract' agent
---
aea/skills/base.py | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/aea/skills/base.py b/aea/skills/base.py
index d7edf469af..7ff9bd6fc4 100644
--- a/aea/skills/base.py
+++ b/aea/skills/base.py
@@ -900,15 +900,19 @@ def _filter_classes(
- the class must be a subclass of "SkillComponent";
- its __module__ attribute must not start with 'aea.' (we exclude classes provided by the framework)
- its __module__ attribute starts with the expected dotted path of this skill.
+ In particular, it should not be imported from another skill.
:param classes: a list of pairs (class name, class object)
:return: a list of the same kind, but filtered with only skill component classes.
"""
filtered_classes = filter(
lambda name_and_class: issubclass(name_and_class[1], SkillComponent)
+ # the following condition filters out classes imported from 'aea'
and not str.startswith(name_and_class[1].__module__, "aea.")
+ # the following condition filters out classes imported
+ # from other skills
and not str.startswith(
- name_and_class[1].__module__, self.skill_dotted_path
+ name_and_class[1].__module__, self.skill_dotted_path + "."
),
classes,
)
@@ -1142,6 +1146,14 @@ def _print_warning_message_for_unused_classes(
set_of_unused_classes = set(
filter(lambda x: x not in used_classes, set_of_classes)
)
+ # filter out classes that are from other packages
+ set_of_unused_classes = set(
+ filter(
+ lambda x: not str.startswith(x.__module__, "packages."),
+ set_of_unused_classes,
+ )
+ )
+
if len(set_of_unused_classes) == 0:
# all classes in the module are used!
continue
From 897896d3fba0d6e7bb70cb37c5c38df2748dc422 Mon Sep 17 00:00:00 2001
From: ali
Date: Mon, 17 May 2021 15:25:21 +0100
Subject: [PATCH 062/147] tests: resolve failed tests
---
.../test_bash_yaml/md_files/bash-ml-skills.md | 9 +++++++++
.../test_bash_yaml/md_files/bash-tac-skills.md | 18 ++++++++++++++++++
.../md_files/bash-thermometer-skills.md | 9 +++++++++
.../md_files/bash-weather-skills.md | 9 +++++++++
4 files changed, 45 insertions(+)
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-ml-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-ml-skills.md
index 34de4e0e17..93fde92b98 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-ml-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-ml-skills.md
@@ -1,4 +1,13 @@
``` bash
+{
+ "delegate_uri": "127.0.0.1:11001",
+ "entry_peers": ["REPLACE_WITH_MULTI_ADDRESS_HERE"],
+ "local_uri": "127.0.0.1:9001",
+ "log_file": "libp2p_node.log",
+ "public_uri": "127.0.0.1:9001"
+}
+```
+``` bash
aea fetch fetchai/ml_data_provider:0.29.0
cd ml_data_provider
aea install
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md
index 71cdbe2606..9a6003ddad 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-tac-skills.md
@@ -1,4 +1,22 @@
``` bash
+{
+ "delegate_uri": "127.0.0.1:11001",
+ "entry_peers": ["REPLACE_WITH_MULTI_ADDRESS_HERE"],
+ "local_uri": "127.0.0.1:9001",
+ "log_file": "libp2p_node.log",
+ "public_uri": "127.0.0.1:9001"
+}
+```
+``` bash
+{
+ "delegate_uri": "127.0.0.1:11002",
+ "entry_peers": ["REPLACE_WITH_MULTI_ADDRESS_HERE"],
+ "local_uri": "127.0.0.1:9002",
+ "log_file": "libp2p_node.log",
+ "public_uri": "127.0.0.1:9002"
+}
+```
+``` bash
aea fetch fetchai/tac_controller:0.27.0
cd tac_controller
aea install
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-thermometer-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-thermometer-skills.md
index f22b86234a..58b0f3a5ad 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-thermometer-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-thermometer-skills.md
@@ -1,3 +1,12 @@
+``` bash
+{
+ "delegate_uri": "127.0.0.1:11001",
+ "entry_peers": ["REPLACE_WITH_MULTI_ADDRESS_HERE"],
+ "local_uri": "127.0.0.1:9001",
+ "log_file": "libp2p_node.log",
+ "public_uri": "127.0.0.1:9001"
+}
+```
``` bash
aea fetch fetchai/thermometer_aea:0.27.0 --alias my_thermometer_aea
cd my_thermometer_aea
diff --git a/tests/test_docs/test_bash_yaml/md_files/bash-weather-skills.md b/tests/test_docs/test_bash_yaml/md_files/bash-weather-skills.md
index 5e56fc6f0d..1837df33d0 100644
--- a/tests/test_docs/test_bash_yaml/md_files/bash-weather-skills.md
+++ b/tests/test_docs/test_bash_yaml/md_files/bash-weather-skills.md
@@ -1,4 +1,13 @@
``` bash
+{
+ "delegate_uri": "127.0.0.1:11001",
+ "entry_peers": ["REPLACE_WITH_MULTI_ADDRESS_HERE"],
+ "local_uri": "127.0.0.1:9001",
+ "log_file": "libp2p_node.log",
+ "public_uri": "127.0.0.1:9001"
+}
+```
+``` bash
aea fetch fetchai/weather_station:0.29.0 --alias my_weather_station
cd my_weather_station
aea install
From 25b44e9a3ebece1acff14c340cd6449d05116030 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Mon, 17 May 2021 16:59:09 +0100
Subject: [PATCH 063/147] feat: update deployment guide re kubernetes
feat: new tac deployment and config improvements
---
docs/deployment.md | 6 +-----
examples/tac_deploy/.env | 1 +
examples/tac_deploy/README.md | 14 ++++++++------
examples/tac_deploy/build.sh | 14 ++++++++++----
examples/tac_deploy/tac-deployment.yaml | 2 +-
5 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/docs/deployment.md b/docs/deployment.md
index 7eac2b9964..2b179a1c18 100644
--- a/docs/deployment.md
+++ b/docs/deployment.md
@@ -17,8 +17,4 @@ Then follow the `README.md` contained in the folder.
## Deployment using Kubernetes
-
-
Note
-
This section is incomplete and will soon be updated.
-
-
+For an example of how to use Kubernets navigate to our TAC deployment example.
diff --git a/examples/tac_deploy/.env b/examples/tac_deploy/.env
index 0fd448f2f1..c451b7199e 100644
--- a/examples/tac_deploy/.env
+++ b/examples/tac_deploy/.env
@@ -1,4 +1,5 @@
PARTICIPANTS_AMOUNT=10
LOG_LEVEL=INFO
USE_CLIENT=false
+PACKAGES_SOURCE=--remote
CLEAR_KEY_DATA_ON_LAUNCH=true
\ No newline at end of file
diff --git a/examples/tac_deploy/README.md b/examples/tac_deploy/README.md
index b1b917ff7e..de314736a9 100644
--- a/examples/tac_deploy/README.md
+++ b/examples/tac_deploy/README.md
@@ -4,14 +4,16 @@ The TAC deployment deploys one controller and `n` tac participants.
### Build the image
-To build the image:
+First, ensure the specifications in `.env` match your requirements.
+
+Then, to build the image run:
``` bash
docker build -t tac-deploy -f Dockerfile . --no-cache
```
## Run locally
-Add preferred amount of tac participants agents to `.env` file:
+Specify preferred amount of tac participants agents in `.env` file, e.g.:
```
PARTICIPANTS_AMOUNT=5
```
@@ -21,7 +23,7 @@ Run:
docker run --env-file .env -v "$(pwd)/data:/data" -ti tac-deploy
```
-## Run in the cloud
+## Run in the cloud (here using GCloud)
GCloud should be configured first!
@@ -29,12 +31,12 @@ GCloud should be configured first!
Tag the image first with the latest tag:
``` bash
-docker image tag tac-deploy gcr.io/fetch-ai-sandbox/tac_deploy:0.0.13
+docker image tag tac-deploy gcr.io/fetch-ai-sandbox/tac_deploy:0.0.14
```
Push it to remote repo:
``` bash
-docker push gcr.io/fetch-ai-sandbox/tac_deploy:0.0.13
+docker push gcr.io/fetch-ai-sandbox/tac_deploy:0.0.14
```
### Run it manually
@@ -67,7 +69,7 @@ find . -name \*.txt -type f -delete
First, push the latest image, as per above.
-Second, update the `tac-deployment.yaml` file and then run:
+Second, update the `tac-deployment.yaml` file with the correct image tag and configurations and then run:
``` bash
kubectl apply -f ./tac-deployment.yaml
```
diff --git a/examples/tac_deploy/build.sh b/examples/tac_deploy/build.sh
index 21e74af0eb..f75641281d 100644
--- a/examples/tac_deploy/build.sh
+++ b/examples/tac_deploy/build.sh
@@ -7,27 +7,33 @@ then
fi
echo USE_CLIENT $USE_CLIENT
+if [ -z "$PACKAGES_SOURCE" ];
+then
+ PACKAGES_SOURCE="--remote"
+fi
+echo PACKAGES_SOURCE $PACKAGES_SOURCE
+
mkdir /data
# setup the agent
-aea fetch fetchai/tac_controller:latest
+aea fetch $PACKAGES_SOURCE fetchai/tac_controller:latest
cd tac_controller
if [[ "$USE_CLIENT" == "true" ]]
then
aea remove connection fetchai/p2p_libp2p
- aea add connection fetchai/p2p_libp2p_client
+ aea add $PACKAGES_SOURCE connection fetchai/p2p_libp2p_client
aea config set agent.default_connection fetchai/p2p_libp2p_client:0.18.0
fi
aea install
aea build
cd ..
-aea fetch fetchai/tac_participant:latest --alias tac_participant_template
+aea fetch $PACKAGES_SOURCE fetchai/tac_participant:latest --alias tac_participant_template
cd tac_participant_template
if [[ "$USE_CLIENT" == "true" ]]
then
aea remove connection fetchai/p2p_libp2p
- aea add connection fetchai/p2p_libp2p_client
+ aea add $PACKAGES_SOURCE connection fetchai/p2p_libp2p_client
aea config set agent.default_connection fetchai/p2p_libp2p_client:0.18.0
fi
aea install
diff --git a/examples/tac_deploy/tac-deployment.yaml b/examples/tac_deploy/tac-deployment.yaml
index 8715709e7d..565669f699 100644
--- a/examples/tac_deploy/tac-deployment.yaml
+++ b/examples/tac_deploy/tac-deployment.yaml
@@ -18,7 +18,7 @@ spec:
kubernetes.io/os: linux
containers:
- name: tac-deploy-container
- image: gcr.io/fetch-ai-sandbox/tac_deploy:0.0.13
+ image: gcr.io/fetch-ai-sandbox/tac_deploy:0.0.14
resources:
requests:
memory: "12000000Ki"
From 6347123e03881dc8c9b1e5f575826a9fd4d7107a Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 17 May 2021 18:14:53 +0200
Subject: [PATCH 064/147] improve error message for local fetch (#2482)
---
aea/cli/utils/package_utils.py | 2 +-
tests/test_cli/test_utils/test_utils.py | 8 ++++++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/aea/cli/utils/package_utils.py b/aea/cli/utils/package_utils.py
index 4c8d19370b..901c32dc84 100644
--- a/aea/cli/utils/package_utils.py
+++ b/aea/cli/utils/package_utils.py
@@ -162,7 +162,7 @@ def try_get_item_source_path(
source_path = os.path.join(path, author_name, item_type_plural, item_name)
if not os.path.exists(source_path):
raise click.ClickException(
- 'Item "{}" not found in source folder.'.format(item_name)
+ f'Item "{author_name}/{item_name}" not found in source folder "{source_path}".'
)
return source_path
diff --git a/tests/test_cli/test_utils/test_utils.py b/tests/test_cli/test_utils/test_utils.py
index 31db550767..ff3b8fa71a 100644
--- a/tests/test_cli/test_utils/test_utils.py
+++ b/tests/test_cli/test_utils/test_utils.py
@@ -133,8 +133,12 @@ def test_get_item_source_path_positive(self, exists_mock, join_mock):
@mock.patch("aea.cli.utils.package_utils.os.path.exists", return_value=False)
def test_get_item_source_path_not_exists(self, exists_mock, join_mock):
"""Test for get_item_source_path item already exists."""
- with self.assertRaises(ClickException):
- try_get_item_source_path("cwd", AUTHOR, "skills", "skill_name")
+ item_name = "skill_name"
+ with pytest.raises(
+ ClickException,
+ match=f'Item "{AUTHOR}/{item_name}" not found in source folder "some-path"',
+ ):
+ try_get_item_source_path("cwd", AUTHOR, "skills", item_name)
@mock.patch("aea.cli.utils.package_utils.os.path.join", return_value="some-path")
From c499d21da7e949d3054702210bb93144511fe9b2 Mon Sep 17 00:00:00 2001
From: David Minarsch
Date: Mon, 17 May 2021 17:27:53 +0100
Subject: [PATCH 065/147] feat: add link to gcloud init
---
examples/tac_deploy/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/tac_deploy/README.md b/examples/tac_deploy/README.md
index de314736a9..ef71ade2fe 100644
--- a/examples/tac_deploy/README.md
+++ b/examples/tac_deploy/README.md
@@ -25,7 +25,7 @@ docker run --env-file .env -v "$(pwd)/data:/data" -ti tac-deploy
## Run in the cloud (here using GCloud)
-GCloud should be configured first!
+GCloud should be [configured](https://cloud.google.com/sdk/docs/initializing) first!
### Push image
From 90a69021c6720be9bfa5914d825ca7aad41f8ec4 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 17 May 2021 19:10:31 +0200
Subject: [PATCH 066/147] fix test in test_push after 6347123e0
---
tests/test_cli/test_push.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tests/test_cli/test_push.py b/tests/test_cli/test_push.py
index 4f041fd7b1..efe1a6aa50 100644
--- a/tests/test_cli/test_push.py
+++ b/tests/test_cli/test_push.py
@@ -90,9 +90,10 @@ def test_vendor_ok(
def test_fail_no_item(
self, *mocks,
):
- """Test fail, item_noit_exists ."""
+ """Test fail, item_not_exists ."""
with pytest.raises(
- ClickException, match='Item "not_exists" not found in source folder.'
+ ClickException,
+ match='Item "fetchai/not_exists" not found in source folder "./vendor/fetchai/skills/not_exists".',
):
self.invoke("push", "--local", "skill", "fetchai/not_exists")
From 9f33c195ceef1feff4bf121bf917add1cc71caa2 Mon Sep 17 00:00:00 2001
From: ali
Date: Mon, 17 May 2021 18:14:36 +0100
Subject: [PATCH 067/147] docs: isolating publi_id strings
---
docs/car-park-skills.md | 2 +-
docs/ml-skills.md | 2 +-
docs/tac-skills.md | 6 +++---
docs/thermometer-skills.md | 2 +-
docs/weather-skills.md | 2 +-
5 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/docs/car-park-skills.md b/docs/car-park-skills.md
index e7b248e4ed..5b2530b78e 100644
--- a/docs/car-park-skills.md
+++ b/docs/car-park-skills.md
@@ -65,7 +65,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `car_detector` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `car_data_buyer` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
+5. Navigate to the settings of the `car_data_buyer` and under `components > connection >` `fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11001",
diff --git a/docs/ml-skills.md b/docs/ml-skills.md
index 933dfde84a..04a8bf2d5e 100644
--- a/docs/ml-skills.md
+++ b/docs/ml-skills.md
@@ -71,7 +71,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `ml_data_provider` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `ml_model_trainer` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
+5. Navigate to the settings of the `ml_model_trainer` and under `components > connection >` `fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11001",
diff --git a/docs/tac-skills.md b/docs/tac-skills.md
index c58d8f5415..46e21d1737 100644
--- a/docs/tac-skills.md
+++ b/docs/tac-skills.md
@@ -105,11 +105,11 @@ The following steps assume you have launched the AEA Manager Desktop app.
3. Add another new AEA called `participant_2` with public id `fetchai/tac_participant:0.28.0`.
-4. Navigate to the settings of `controller` and under `components > skills/fetchai/tac_controller:0.22.0 > models > parameters > args` update `registration_start_time` to the time you want TAC to begin (e.g. 2 minutes in the future)
+4. Navigate to the settings of `controller` and under `components > skill >` `fetchai/fetchai/tac_controller:0.22.0` `> models > parameters > args` update `registration_start_time` to the time you want TAC to begin (e.g. 2 minutes in the future)
5. Run the `controller` AEA. Navigate to its logs and copy the multiaddress displayed. Stop the `controller`.
-5. Navigate to the settings of `participant_1` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
+5. Navigate to the settings of `participant_1` and under `components > connection >` `fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11001",
@@ -120,7 +120,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
}
```
-6. Navigate to the settings of `participant_2` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
+6. Navigate to the settings of `participant_2` and under `components > connection >` `fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11002",
diff --git a/docs/thermometer-skills.md b/docs/thermometer-skills.md
index 5db274e192..4009f722e4 100644
--- a/docs/thermometer-skills.md
+++ b/docs/thermometer-skills.md
@@ -63,7 +63,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `my_thermometer_aea` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `my_thermometer_client` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
+5. Navigate to the settings of the `my_thermometer_client` and under `components > connection >` `fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11001",
diff --git a/docs/weather-skills.md b/docs/weather-skills.md
index 8336259a12..afa5e97e41 100644
--- a/docs/weather-skills.md
+++ b/docs/weather-skills.md
@@ -67,7 +67,7 @@ The following steps assume you have launched the AEA Manager Desktop app.
4. Run the `my_weather_station` AEA. Navigate to its logs and copy the multiaddress displayed.
-5. Navigate to the settings of the `my_weather_client` and under `components > connections/fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
+5. Navigate to the settings of the `my_weather_client` and under `components > connection >` `fetchai/p2p_libp2p:0.22.0` update as follows (make sure to replace the placeholder with the multiaddress):
``` bash
{
"delegate_uri": "127.0.0.1:11001",
From 1fbfebf8ddb74de9ec3b935f26c7959fe09ad266 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 17 May 2021 19:48:22 +0200
Subject: [PATCH 068/147] add log info message if loaded component is abstract
(#2474)
---
aea/aea_builder.py | 4 ++++
tests/test_aea_builder.py | 32 ++++++++++++++++++++++++++------
2 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/aea/aea_builder.py b/aea/aea_builder.py
index 07aa81df12..bc1dc946ad 100644
--- a/aea/aea_builder.py
+++ b/aea/aea_builder.py
@@ -1918,6 +1918,10 @@ def _load_and_add_components(
new_configuration = self._overwrite_custom_configuration(configuration)
if new_configuration.is_abstract_component:
load_aea_package(configuration)
+ self.logger.info(
+ f"Package {configuration.public_id} of type {configuration.component_type} is abstract, "
+ f"therefore only the Python modules have been loaded."
+ )
continue
_logger = make_component_logger(new_configuration, agent_name)
component = load_component_from_config(
diff --git a/tests/test_aea_builder.py b/tests/test_aea_builder.py
index 29b4f6ac06..666f64dc33 100644
--- a/tests/test_aea_builder.py
+++ b/tests/test_aea_builder.py
@@ -596,16 +596,36 @@ def test_set_from_config_custom():
def test_load_abstract_component():
"""Test abstract component loading."""
+ resources = Resources()
builder = AEABuilder()
builder.set_name("aea_1")
builder.add_private_key("fetchai")
- skill = Skill.from_dir(dummy_skill_path, Mock(agent_name="name"))
- skill.configuration.is_abstract = True
- builder.add_component_instance(skill)
- builder._load_and_add_components(
- ComponentType.SKILL, Resources(), "aea_1", agent_context=Mock(agent_name="name")
- )
+ builder.add_component(ComponentType.SKILL, dummy_skill_path)
+ with mock.patch(
+ "aea.aea_builder.load_aea_package", return_value=True
+ ), mock.patch.object(
+ builder,
+ "_overwrite_custom_configuration",
+ return_value=Mock(is_abstract_component=True),
+ ), mock.patch.object(
+ builder.logger, "info"
+ ) as mock_logger:
+ builder._load_and_add_components(
+ ComponentType.SKILL,
+ resources,
+ "aea_1",
+ agent_context=Mock(agent_name="name"),
+ )
+
+ mock_logger.assert_called_with(
+ f"Package {DUMMY_SKILL_PUBLIC_ID} of type skill is abstract, "
+ f"therefore only the Python modules have been loaded."
+ )
+
+ assert (
+ len(resources.get_all_skills()) == 0
+ ), "expected 0 skills because the loaded skill is abstract"
def test_find_import_order():
From 476dd3e88a1c00f1b5926885367698a754f024b1 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 17 May 2021 19:52:14 +0200
Subject: [PATCH 069/147] remove useless mock return value in
'test_load_abstract_component'
---
tests/test_aea_builder.py | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/tests/test_aea_builder.py b/tests/test_aea_builder.py
index 666f64dc33..27cef0b50f 100644
--- a/tests/test_aea_builder.py
+++ b/tests/test_aea_builder.py
@@ -602,15 +602,11 @@ def test_load_abstract_component():
builder.add_private_key("fetchai")
builder.add_component(ComponentType.SKILL, dummy_skill_path)
- with mock.patch(
- "aea.aea_builder.load_aea_package", return_value=True
- ), mock.patch.object(
+ with mock.patch("aea.aea_builder.load_aea_package"), mock.patch.object(
builder,
"_overwrite_custom_configuration",
return_value=Mock(is_abstract_component=True),
- ), mock.patch.object(
- builder.logger, "info"
- ) as mock_logger:
+ ), mock.patch.object(builder.logger, "info") as mock_logger:
builder._load_and_add_components(
ComponentType.SKILL,
resources,
From 3cc2a3ae30e76ff6e0ebb305b5b7da3b33d8ed44 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 17 May 2021 21:27:56 +0200
Subject: [PATCH 070/147] use debug level instead of info level
---
aea/aea_builder.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/aea/aea_builder.py b/aea/aea_builder.py
index bc1dc946ad..2dad9e0013 100644
--- a/aea/aea_builder.py
+++ b/aea/aea_builder.py
@@ -1918,7 +1918,7 @@ def _load_and_add_components(
new_configuration = self._overwrite_custom_configuration(configuration)
if new_configuration.is_abstract_component:
load_aea_package(configuration)
- self.logger.info(
+ self.logger.debug(
f"Package {configuration.public_id} of type {configuration.component_type} is abstract, "
f"therefore only the Python modules have been loaded."
)
From 27ffe24ee56b354961014feb95db13abed49bef9 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Mon, 17 May 2021 21:55:32 +0200
Subject: [PATCH 071/147] make test cross-platform
---
tests/test_cli/test_push.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tests/test_cli/test_push.py b/tests/test_cli/test_push.py
index efe1a6aa50..7f0292bea5 100644
--- a/tests/test_cli/test_push.py
+++ b/tests/test_cli/test_push.py
@@ -18,6 +18,7 @@
# ------------------------------------------------------------------------------
"""Test module for Registry push methods."""
import filecmp
+import os.path
from unittest import TestCase, mock
import pytest
@@ -91,9 +92,12 @@ def test_fail_no_item(
self, *mocks,
):
"""Test fail, item_not_exists ."""
+ expected_path_string = os.path.join(
+ ".", "vendor", "fetchai", "skills", "not_exists"
+ )
with pytest.raises(
ClickException,
- match='Item "fetchai/not_exists" not found in source folder "./vendor/fetchai/skills/not_exists".',
+ match=f'Item "fetchai/not_exists" not found in source folder "{expected_path_string}".',
):
self.invoke("push", "--local", "skill", "fetchai/not_exists")
From 5098ff72e2d6b545f5cddd823cb99a2b66972524 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 11:33:27 +0200
Subject: [PATCH 072/147] test: update log level in
'test_load_abstract_component'
---
tests/test_aea_builder.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/test_aea_builder.py b/tests/test_aea_builder.py
index 27cef0b50f..8e51efde23 100644
--- a/tests/test_aea_builder.py
+++ b/tests/test_aea_builder.py
@@ -606,7 +606,7 @@ def test_load_abstract_component():
builder,
"_overwrite_custom_configuration",
return_value=Mock(is_abstract_component=True),
- ), mock.patch.object(builder.logger, "info") as mock_logger:
+ ), mock.patch.object(builder.logger, "debug") as mock_logger:
builder._load_and_add_components(
ComponentType.SKILL,
resources,
From 2c922fc54fb9c16623b1ffb65f2d5ce4dfb73dc3 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 11:49:13 +0200
Subject: [PATCH 073/147] test: try to make the test
'TestPushLocally.test_fail_no_item' to pass on windows
---
tests/test_cli/test_push.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/test_cli/test_push.py b/tests/test_cli/test_push.py
index 7f0292bea5..fd0d1da985 100644
--- a/tests/test_cli/test_push.py
+++ b/tests/test_cli/test_push.py
@@ -93,11 +93,11 @@ def test_fail_no_item(
):
"""Test fail, item_not_exists ."""
expected_path_string = os.path.join(
- ".", "vendor", "fetchai", "skills", "not_exists"
+ r"\.", "vendor", "fetchai", "skills", "not_exists"
)
with pytest.raises(
ClickException,
- match=f'Item "fetchai/not_exists" not found in source folder "{expected_path_string}".',
+ match=rf'Item "fetchai/not_exists" not found in source folder "{expected_path_string}"\.',
):
self.invoke("push", "--local", "skill", "fetchai/not_exists")
From f10c29bf89e3d22e1f39781fe53c06301c41b6a8 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 14:06:27 +0200
Subject: [PATCH 074/147] trigger CI
From c98ae38ce6764f7eb460c491bf2655583afc5089 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 14:07:08 +0200
Subject: [PATCH 075/147] trigger CI
From 91d6e113e7c7d95967c2e614061153049be4704c Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 15:15:39 +0200
Subject: [PATCH 076/147] add tests on manager with passwords
---
tests/test_manager/test_manager.py | 49 ++++++++++++++++++++++++------
1 file changed, 39 insertions(+), 10 deletions(-)
diff --git a/tests/test_manager/test_manager.py b/tests/test_manager/test_manager.py
index 630913c6fa..252c61dc05 100644
--- a/tests/test_manager/test_manager.py
+++ b/tests/test_manager/test_manager.py
@@ -20,6 +20,7 @@
import asyncio
import os
import re
+import sys
from contextlib import suppress
from pathlib import Path
from shutil import rmtree
@@ -44,12 +45,11 @@
@patch("aea.aea_builder.AEABuilder.install_pypi_dependencies")
-class TestMultiAgentManagerAsyncMode(
- TestCase
-): # pylint: disable=unused-argument,protected-access,attribute-defined-outside-init
- """Tests for MultiAgentManager in async mode."""
+class BaseTestMultiAgentManager(TestCase):
+ """Base test class for multi-agent manager"""
MODE = "async"
+ PASSWORD = None
echo_skill_id = ECHO_SKILL_PUBLIC_ID
@@ -62,7 +62,9 @@ def setUp(self):
self.working_dir, self.project_public_id.author, self.project_public_id.name
)
assert not os.path.exists(self.working_dir)
- self.manager = MultiAgentManager(self.working_dir, mode=self.MODE)
+ self.manager = MultiAgentManager(
+ self.working_dir, mode=self.MODE, password=self.PASSWORD
+ )
def tearDown(self):
"""Tear down test case."""
@@ -73,10 +75,14 @@ def tearDown(self):
def test_plugin_dependencies(self, *args):
"""Test plugin installed and loaded as a depencndecy."""
plugin_path = str(Path(ROOT_DIR) / "plugins" / "aea-ledger-fetchai")
- install_cmd = f"pip install --no-deps {plugin_path}".split(" ")
+ install_cmd = f"{sys.executable} -m pip install --no-deps {plugin_path}".split(
+ " "
+ )
try:
self.manager.start_manager()
- run_install_subprocess("pip uninstall aea-ledger-fetchai -y".split(" "))
+ run_install_subprocess(
+ f"{sys.executable} -m pip uninstall aea-ledger-fetchai -y".split(" ")
+ )
from aea.crypto.registries import ledger_apis_registry
ledger_apis_registry.specs.pop("fetchai", None)
@@ -98,7 +104,9 @@ def install_deps(*_):
assert "fetchai" in ledger_apis_registry.specs
finally:
- run_install_subprocess("pip uninstall aea-ledger-fetchai -y".split(" "))
+ run_install_subprocess(
+ f"{sys.executable} -m pip uninstall aea-ledger-fetchai -y".split(" ")
+ )
run_install_subprocess(install_cmd)
def test_workdir_created_removed(self, *args):
@@ -457,7 +465,7 @@ def test_issue_certificates(self, *args):
assert not os.path.exists(cert_filename)
priv_key_path = os.path.abspath(os.path.join(self.working_dir, "priv_key.txt"))
- create_private_key("fetchai", priv_key_path)
+ create_private_key("fetchai", priv_key_path, password=self.PASSWORD)
assert os.path.exists(priv_key_path)
component_overrides = [
@@ -528,12 +536,33 @@ def test_addresses_autoadded(self, *args) -> None:
assert len(agent_alias.get_connections_addresses()) == 1
-class TestMultiAgentManagerThreadedMode(TestMultiAgentManagerAsyncMode):
+class TestMultiAgentManagerAsyncMode(
+ BaseTestMultiAgentManager
+): # pylint: disable=unused-argument,protected-access,attribute-defined-outside-init
+ """Tests for MultiAgentManager in async mode."""
+
+
+class TestMultiAgentManagerAsyncModeWithPassword(
+ BaseTestMultiAgentManager
+): # pylint: disable=unused-argument,protected-access,attribute-defined-outside-init
+ """Tests for MultiAgentManager in async mode, with password."""
+
+ PASSWORD = "password"
+
+
+class TestMultiAgentManagerThreadedMode(BaseTestMultiAgentManager):
"""Tests for MultiAgentManager in threaded mode."""
MODE = "threaded"
+class TestMultiAgentManagerThreadedModeWithPassword(BaseTestMultiAgentManager):
+ """Tests for MultiAgentManager in threaded mode, with password."""
+
+ MODE = "threaded"
+ PASSWORD = "password"
+
+
def test_project_auto_added_removed():
"""Check project auto added and auto removed on agent added/removed."""
agent_name = "test_agent"
From 398475d0634ba85fffb278ba5567613bf29c6793 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 16:30:20 +0200
Subject: [PATCH 077/147] fix: fix bandit checks
---
tests/test_manager/test_manager.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/test_manager/test_manager.py b/tests/test_manager/test_manager.py
index 252c61dc05..8bddd28074 100644
--- a/tests/test_manager/test_manager.py
+++ b/tests/test_manager/test_manager.py
@@ -547,7 +547,7 @@ class TestMultiAgentManagerAsyncModeWithPassword(
): # pylint: disable=unused-argument,protected-access,attribute-defined-outside-init
"""Tests for MultiAgentManager in async mode, with password."""
- PASSWORD = "password"
+ PASSWORD = "password" # nosec
class TestMultiAgentManagerThreadedMode(BaseTestMultiAgentManager):
@@ -560,7 +560,7 @@ class TestMultiAgentManagerThreadedModeWithPassword(BaseTestMultiAgentManager):
"""Tests for MultiAgentManager in threaded mode, with password."""
MODE = "threaded"
- PASSWORD = "password"
+ PASSWORD = "password" # nosec
def test_project_auto_added_removed():
From eeb4a59cdde77d8556f7d9bec2854bf571b59607 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 21:54:36 +0200
Subject: [PATCH 078/147] add test on 'aea generate-key' with '--password'
---
tests/test_cli/test_generate_key.py | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/tests/test_cli/test_generate_key.py b/tests/test_cli/test_generate_key.py
index 86adbf0273..8b700cd79f 100644
--- a/tests/test_cli/test_generate_key.py
+++ b/tests/test_cli/test_generate_key.py
@@ -29,6 +29,7 @@
from aea.cli import cli
from aea.crypto.registries import make_crypto
+from aea.test_tools.test_cases import AEATestCaseEmpty
from tests.conftest import (
CLI_LOG_OPTION,
@@ -181,3 +182,23 @@ def teardown_class(cls):
"""Tear the test down."""
os.chdir(cls.cwd)
shutil.rmtree(cls.t)
+
+
+class TestGenerateKeyWithPassword(AEATestCaseEmpty):
+ """Test that the command 'aea generate-key' with a password argument works as expected."""
+
+ def test_fetchai(self):
+ """Test that the fetch private key is created correctly."""
+ password = "password"
+ result = self.run_cli_command(
+ "generate-key", FetchAICrypto.identifier, "--password", password
+ )
+ assert result.exit_code == 0
+ assert Path(FETCHAI_PRIVATE_KEY_FILE).exists()
+
+ # check the key can be read again with the same password.
+ make_crypto(
+ FetchAICrypto.identifier,
+ private_key_path=FETCHAI_PRIVATE_KEY_FILE,
+ password=password,
+ )
From 547c4d6557a79418d29f62b792a994b2211817f5 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 22:22:01 +0200
Subject: [PATCH 079/147] add test on 'aea add-key' with '--password'
---
tests/test_cli/test_add_key.py | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/tests/test_cli/test_add_key.py b/tests/test_cli/test_add_key.py
index b872db19a3..45ddbed745 100644
--- a/tests/test_cli/test_add_key.py
+++ b/tests/test_cli/test_add_key.py
@@ -33,6 +33,7 @@
from aea.cli import cli
from aea.cli.add_key import _try_add_key
from aea.configurations.base import AgentConfig, DEFAULT_AEA_CONFIG_FILE
+from aea.test_tools.test_cases import AEATestCaseEmpty
from tests.conftest import (
AUTHOR,
@@ -428,3 +429,32 @@ def test_file_not_specified_does_not_exist(self, *mocks):
standalone_mode=False,
catch_exceptions=False,
)
+
+
+class TestAddKeyWithPassword(AEATestCaseEmpty):
+ """Test the '--password' option to 'add-key' command."""
+
+ FAKE_PASSWORD = "password"
+
+ @classmethod
+ def setup_class(cls) -> None:
+ """Set up the class."""
+ super().setup_class()
+ cls.run_cli_command(
+ "generate-key",
+ FetchAICrypto.identifier,
+ FETCHAI_PRIVATE_KEY_FILE,
+ "--password",
+ cls.FAKE_PASSWORD,
+ cwd=cls._get_cwd(),
+ )
+
+ def test_add_key_with_password(self):
+ """Test add key with password."""
+ self.run_cli_command(
+ "add-key",
+ FetchAICrypto.identifier,
+ "--password",
+ self.FAKE_PASSWORD,
+ cwd=self._get_cwd(),
+ )
From ccd80f5811ccba5d6f409e18ee5fac3338cc013a Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 22:26:38 +0200
Subject: [PATCH 080/147] fix static check in test_manager.py
---
tests/test_manager/test_manager.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/tests/test_manager/test_manager.py b/tests/test_manager/test_manager.py
index 8bddd28074..d4738e5421 100644
--- a/tests/test_manager/test_manager.py
+++ b/tests/test_manager/test_manager.py
@@ -25,6 +25,7 @@
from pathlib import Path
from shutil import rmtree
from tempfile import TemporaryDirectory
+from typing import Optional
from unittest.case import TestCase
from unittest.mock import Mock, patch
@@ -49,7 +50,7 @@ class BaseTestMultiAgentManager(TestCase):
"""Base test class for multi-agent manager"""
MODE = "async"
- PASSWORD = None
+ PASSWORD: Optional[str] = None
echo_skill_id = ECHO_SKILL_PUBLIC_ID
From dbbfc8309cb2ee14b9e74a14cf5d5b243c090b8b Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 22:38:02 +0200
Subject: [PATCH 081/147] use parametrized fixture for tests that use passwords
---
tests/conftest.py | 10 ++++++
tests/test_cli/test_generate_key.py | 56 +++++++++++++----------------
2 files changed, 35 insertions(+), 31 deletions(-)
diff --git a/tests/conftest.py b/tests/conftest.py
index 5f98fa6a19..1021d59e52 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1437,3 +1437,13 @@ def change_directory():
yield temporary_directory
finally:
shutil.rmtree(temporary_directory)
+
+
+@pytest.fixture(params=[None, "fake-password"])
+def password_or_none(request) -> Optional[str]:
+ """
+ Return a password for testing purposes.
+
+ Note that this is a parametrized fixture.
+ """
+ return request.param
diff --git a/tests/test_cli/test_generate_key.py b/tests/test_cli/test_generate_key.py
index 8b700cd79f..918e0264ab 100644
--- a/tests/test_cli/test_generate_key.py
+++ b/tests/test_cli/test_generate_key.py
@@ -23,13 +23,13 @@
import shutil
import tempfile
from pathlib import Path
+from typing import List, Optional
from aea_ledger_ethereum import EthereumCrypto
from aea_ledger_fetchai import FetchAICrypto
from aea.cli import cli
from aea.crypto.registries import make_crypto
-from aea.test_tools.test_cases import AEATestCaseEmpty
from tests.conftest import (
CLI_LOG_OPTION,
@@ -51,26 +51,40 @@ def setup_class(cls):
cls.t = tempfile.mkdtemp()
os.chdir(cls.t)
- def test_fetchai(self):
+ def _append_password_option_if_not_none(
+ self, args, password: Optional[str]
+ ) -> List:
+ """Append '--password' option if not None."""
+ if password is None:
+ return args
+ return args + ["--password", password]
+
+ def test_fetchai(self, password):
"""Test that the fetch private key is created correctly."""
- result = self.runner.invoke(
- cli, [*CLI_LOG_OPTION, "generate-key", FetchAICrypto.identifier]
- )
+ args = [*CLI_LOG_OPTION, "generate-key", FetchAICrypto.identifier]
+ args = self._append_password_option_if_not_none(args, password)
+ result = self.runner.invoke(cli, args)
assert result.exit_code == 0
assert Path(FETCHAI_PRIVATE_KEY_FILE).exists()
- make_crypto(FetchAICrypto.identifier, private_key_path=FETCHAI_PRIVATE_KEY_FILE)
+ make_crypto(
+ FetchAICrypto.identifier,
+ private_key_path=FETCHAI_PRIVATE_KEY_FILE,
+ password=password,
+ )
Path(FETCHAI_PRIVATE_KEY_FILE).unlink()
- def test_ethereum(self):
+ def test_ethereum(self, password):
"""Test that the fetch private key is created correctly."""
- result = self.runner.invoke(
- cli, [*CLI_LOG_OPTION, "generate-key", EthereumCrypto.identifier]
- )
+ args = [*CLI_LOG_OPTION, "generate-key", EthereumCrypto.identifier]
+ args = self._append_password_option_if_not_none(args, password)
+ result = self.runner.invoke(cli, args)
assert result.exit_code == 0
assert Path(ETHEREUM_PRIVATE_KEY_FILE).exists()
make_crypto(
- EthereumCrypto.identifier, private_key_path=ETHEREUM_PRIVATE_KEY_FILE
+ EthereumCrypto.identifier,
+ private_key_path=ETHEREUM_PRIVATE_KEY_FILE,
+ password=password,
)
Path(ETHEREUM_PRIVATE_KEY_FILE).unlink()
@@ -182,23 +196,3 @@ def teardown_class(cls):
"""Tear the test down."""
os.chdir(cls.cwd)
shutil.rmtree(cls.t)
-
-
-class TestGenerateKeyWithPassword(AEATestCaseEmpty):
- """Test that the command 'aea generate-key' with a password argument works as expected."""
-
- def test_fetchai(self):
- """Test that the fetch private key is created correctly."""
- password = "password"
- result = self.run_cli_command(
- "generate-key", FetchAICrypto.identifier, "--password", password
- )
- assert result.exit_code == 0
- assert Path(FETCHAI_PRIVATE_KEY_FILE).exists()
-
- # check the key can be read again with the same password.
- make_crypto(
- FetchAICrypto.identifier,
- private_key_path=FETCHAI_PRIVATE_KEY_FILE,
- password=password,
- )
From bc29a0018d714af195c8d7789a7059321c86f25f Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 22:56:58 +0200
Subject: [PATCH 082/147] test: update tests
- update some test_tools APIs so to include an optional parameter 'password'
- add parametrized password fixture: any test that uses it will be run both
with password=None and password="fake-password"
- update generate-key test with new APIs
- extend existing generate-wealth test with new APIs
---
aea/test_tools/test_cases.py | 38 +++++++++++++++++++++++---
tests/conftest.py | 2 +-
tests/test_cli/test_generate_key.py | 27 +++++++-----------
tests/test_cli/test_generate_wealth.py | 8 +++---
4 files changed, 49 insertions(+), 26 deletions(-)
diff --git a/aea/test_tools/test_cases.py b/aea/test_tools/test_cases.py
index 6523786e9a..ac8af5693f 100644
--- a/aea/test_tools/test_cases.py
+++ b/aea/test_tools/test_cases.py
@@ -579,7 +579,10 @@ def run_install(cls) -> Result:
@classmethod
def generate_private_key(
- cls, ledger_api_id: str = DEFAULT_LEDGER, private_key_file: Optional[str] = None
+ cls,
+ ledger_api_id: str = DEFAULT_LEDGER,
+ private_key_file: Optional[str] = None,
+ password: Optional[str] = None,
) -> Result:
"""
Generate AEA private key with CLI command.
@@ -588,12 +591,14 @@ def generate_private_key(
:param ledger_api_id: ledger API ID.
:param private_key_file: the private key file.
+ :param password: the password option.
:return: Result
"""
cli_args = ["generate-key", ledger_api_id]
if private_key_file is not None: # pragma: nocover
cli_args.append(private_key_file)
+ cli_args += _get_password_option_args(password)
return cls.run_cli_command(*cli_args, cwd=cls._get_cwd())
@classmethod
@@ -602,6 +607,7 @@ def add_private_key(
ledger_api_id: str = DEFAULT_LEDGER,
private_key_filepath: str = DEFAULT_PRIVATE_KEY_FILE,
connection: bool = False,
+ password: Optional[str] = None,
) -> Result:
"""
Add private key with CLI command.
@@ -614,16 +620,22 @@ def add_private_key(
:return: Result
"""
+ password_option = _get_password_option_args(password)
if connection:
return cls.run_cli_command(
"add-key",
ledger_api_id,
private_key_filepath,
"--connection",
+ *password_option,
cwd=cls._get_cwd(),
)
return cls.run_cli_command(
- "add-key", ledger_api_id, private_key_filepath, cwd=cls._get_cwd()
+ "add-key",
+ ledger_api_id,
+ private_key_filepath,
+ *password_option,
+ cwd=cls._get_cwd(),
)
@classmethod
@@ -661,18 +673,26 @@ def replace_private_key_in_file(
f.write(private_key)
@classmethod
- def generate_wealth(cls, ledger_api_id: str = DEFAULT_LEDGER) -> Result:
+ def generate_wealth(
+ cls, ledger_api_id: str = DEFAULT_LEDGER, password: Optional[str] = None
+ ) -> Result:
"""
Generate wealth with CLI command.
Run from agent's directory.
:param ledger_api_id: ledger API ID.
+ :param password: the password option.
:return: Result
"""
+ password_option = _get_password_option_args(password)
return cls.run_cli_command(
- "generate-wealth", ledger_api_id, "--sync", cwd=cls._get_cwd()
+ "generate-wealth",
+ ledger_api_id,
+ *password_option,
+ "--sync",
+ cwd=cls._get_cwd(),
)
@classmethod
@@ -936,6 +956,16 @@ def teardown_class(cls) -> None:
cls._is_teardown_class_called = True
+def _get_password_option_args(password: Optional[str]):
+ """
+ Get password option arguments.
+
+ :param password: the password (optional).
+ :return: empty list if password is None, else ['--password', password].
+ """
+ return [] if password is None else ["--password", password]
+
+
class AEATestCaseEmpty(BaseAEATestCase):
"""
Test case for a default AEA project.
diff --git a/tests/conftest.py b/tests/conftest.py
index 1021d59e52..f2d3999f51 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1442,7 +1442,7 @@ def change_directory():
@pytest.fixture(params=[None, "fake-password"])
def password_or_none(request) -> Optional[str]:
"""
- Return a password for testing purposes.
+ Return a password for testing purposes, including None.
Note that this is a parametrized fixture.
"""
diff --git a/tests/test_cli/test_generate_key.py b/tests/test_cli/test_generate_key.py
index 918e0264ab..2b15385450 100644
--- a/tests/test_cli/test_generate_key.py
+++ b/tests/test_cli/test_generate_key.py
@@ -23,7 +23,6 @@
import shutil
import tempfile
from pathlib import Path
-from typing import List, Optional
from aea_ledger_ethereum import EthereumCrypto
from aea_ledger_fetchai import FetchAICrypto
@@ -51,40 +50,34 @@ def setup_class(cls):
cls.t = tempfile.mkdtemp()
os.chdir(cls.t)
- def _append_password_option_if_not_none(
- self, args, password: Optional[str]
- ) -> List:
- """Append '--password' option if not None."""
- if password is None:
- return args
- return args + ["--password", password]
-
- def test_fetchai(self, password):
+ def test_fetchai(self, password_or_none):
"""Test that the fetch private key is created correctly."""
- args = [*CLI_LOG_OPTION, "generate-key", FetchAICrypto.identifier]
- args = self._append_password_option_if_not_none(args, password)
+ args = [*CLI_LOG_OPTION, "generate-key", FetchAICrypto.identifier] + (
+ ["--password", password_or_none] if password_or_none is not None else []
+ )
result = self.runner.invoke(cli, args)
assert result.exit_code == 0
assert Path(FETCHAI_PRIVATE_KEY_FILE).exists()
make_crypto(
FetchAICrypto.identifier,
private_key_path=FETCHAI_PRIVATE_KEY_FILE,
- password=password,
+ password=password_or_none,
)
Path(FETCHAI_PRIVATE_KEY_FILE).unlink()
- def test_ethereum(self, password):
+ def test_ethereum(self, password_or_none):
"""Test that the fetch private key is created correctly."""
- args = [*CLI_LOG_OPTION, "generate-key", EthereumCrypto.identifier]
- args = self._append_password_option_if_not_none(args, password)
+ args = [*CLI_LOG_OPTION, "generate-key", EthereumCrypto.identifier] + (
+ ["--password", password_or_none] if password_or_none is not None else []
+ )
result = self.runner.invoke(cli, args)
assert result.exit_code == 0
assert Path(ETHEREUM_PRIVATE_KEY_FILE).exists()
make_crypto(
EthereumCrypto.identifier,
private_key_path=ETHEREUM_PRIVATE_KEY_FILE,
- password=password,
+ password=password_or_none,
)
Path(ETHEREUM_PRIVATE_KEY_FILE).unlink()
diff --git a/tests/test_cli/test_generate_wealth.py b/tests/test_cli/test_generate_wealth.py
index cb4fb4c2df..e98939cce1 100644
--- a/tests/test_cli/test_generate_wealth.py
+++ b/tests/test_cli/test_generate_wealth.py
@@ -83,17 +83,17 @@ class TestWealthCommandsPositive(AEATestCaseManyFlaky):
@pytest.mark.integration
@pytest.mark.flaky(reruns=MAX_FLAKY_RERUNS_INTEGRATION)
- def test_wealth_commands(self):
+ def test_wealth_commands(self, password_or_none):
"""Test wealth commands."""
agent_name = "test_aea"
self.create_agents(agent_name)
self.set_agent_context(agent_name)
- self.generate_private_key()
- self.add_private_key()
+ self.generate_private_key(password=password_or_none)
+ self.add_private_key(password=password_or_none)
- self.generate_wealth()
+ self.generate_wealth(password=password_or_none)
class TestWealthCommandsNegative(AEATestCaseMany):
From 77755d386c1a46c27f1bf2ae985c2fcbdf905873 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 23:26:45 +0200
Subject: [PATCH 083/147] test: add bandit check to add-key test
---
tests/test_cli/test_add_key.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests/test_cli/test_add_key.py b/tests/test_cli/test_add_key.py
index 45ddbed745..cb96cd3181 100644
--- a/tests/test_cli/test_add_key.py
+++ b/tests/test_cli/test_add_key.py
@@ -434,7 +434,7 @@ def test_file_not_specified_does_not_exist(self, *mocks):
class TestAddKeyWithPassword(AEATestCaseEmpty):
"""Test the '--password' option to 'add-key' command."""
- FAKE_PASSWORD = "password"
+ FAKE_PASSWORD = "password" # nosec
@classmethod
def setup_class(cls) -> None:
From 5136d3ac2c58c117c529edf44ee25fd6d4cc3214 Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Tue, 18 May 2021 23:27:01 +0200
Subject: [PATCH 084/147] add test on 'aea get-address' command with
'--password'
---
tests/test_cli/test_get_address.py | 43 +++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/tests/test_cli/test_get_address.py b/tests/test_cli/test_get_address.py
index 6b340aff28..6b9f40be4f 100644
--- a/tests/test_cli/test_get_address.py
+++ b/tests/test_cli/test_get_address.py
@@ -17,7 +17,6 @@
#
# ------------------------------------------------------------------------------
"""This test module contains the tests for commands in aea.cli.get_address module."""
-
from unittest import TestCase, mock
from unittest.mock import MagicMock
@@ -25,6 +24,8 @@
from aea.cli import cli
from aea.cli.get_address import _try_get_address
+from aea.configurations.constants import DEFAULT_LEDGER
+from aea.test_tools.test_cases import AEATestCaseEmpty
from tests.conftest import CLI_LOG_OPTION, COSMOS_ADDRESS_ONE, CliRunner
from tests.test_cli.tools_for_testing import ContextMock
@@ -67,3 +68,43 @@ def test_run_positive(self, *mocks):
standalone_mode=False,
)
self.assertEqual(result.exit_code, 0)
+
+
+class TestGetAddressCommand(AEATestCaseEmpty):
+ """Test 'get-address' command."""
+
+ @classmethod
+ def setup_class(cls) -> None:
+ """
+ Override the 'setup_class' method.
+
+ This will prevent setup of tests at class-level.
+ """
+
+ def setup(self):
+ """Set up the test."""
+ super().setup_class()
+
+ def test_get_address(self, password_or_none):
+ """Run the main test."""
+ self.generate_private_key(password=password_or_none)
+ self.add_private_key(password=password_or_none)
+
+ password_option = ["--password", password_or_none] if password_or_none else []
+ result = self.run_cli_command(
+ "get-address", DEFAULT_LEDGER, *password_option, cwd=self._get_cwd()
+ )
+
+ assert result.exit_code == 0
+
+ def teardown(self) -> None:
+ """Tear down the test."""
+ super().teardown_class()
+
+ @classmethod
+ def teardown_class(cls) -> None:
+ """
+ Override the 'teardown_class' method.
+
+ This will prevent teardown of tests at class-level.
+ """
From da640d9bdec58995aa1839d61a85aef993e0a5af Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Wed, 19 May 2021 09:50:50 +0200
Subject: [PATCH 085/147] fix: return type missing
---
aea/test_tools/test_cases.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/aea/test_tools/test_cases.py b/aea/test_tools/test_cases.py
index ac8af5693f..3a7ed74e38 100644
--- a/aea/test_tools/test_cases.py
+++ b/aea/test_tools/test_cases.py
@@ -956,7 +956,7 @@ def teardown_class(cls) -> None:
cls._is_teardown_class_called = True
-def _get_password_option_args(password: Optional[str]):
+def _get_password_option_args(password: Optional[str]) -> List[str]:
"""
Get password option arguments.
From 1c6a80beadea3f41648c105304290a31adfac0fc Mon Sep 17 00:00:00 2001
From: MarcoFavorito
Date: Wed, 19 May 2021 09:56:17 +0200
Subject: [PATCH 086/147] test: use pattern instead of os.path.join for
'test_fail_no_item'
---
tests/test_cli/test_push.py | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/tests/test_cli/test_push.py b/tests/test_cli/test_push.py
index fd0d1da985..3bb54433dc 100644
--- a/tests/test_cli/test_push.py
+++ b/tests/test_cli/test_push.py
@@ -18,7 +18,6 @@
# ------------------------------------------------------------------------------
"""Test module for Registry push methods."""
import filecmp
-import os.path
from unittest import TestCase, mock
import pytest
@@ -92,12 +91,12 @@ def test_fail_no_item(
self, *mocks,
):
"""Test fail, item_not_exists ."""
- expected_path_string = os.path.join(
- r"\.", "vendor", "fetchai", "skills", "not_exists"
+ expected_path_pattern = ".*" + ".*".join(
+ ["vendor", "fetchai", "skills", "not_exists"]
)
with pytest.raises(
ClickException,
- match=rf'Item "fetchai/not_exists" not found in source folder "{expected_path_string}"\.',
+ match=rf'Item "fetchai/not_exists" not found in source folder "{expected_path_pattern}"\.',
):
self.invoke("push", "--local", "skill", "fetchai/not_exists")
From e4fe341b3d833d61bf5a21c563d28917eeae7fb9 Mon Sep 17 00:00:00 2001
From: Marco Favorito
Date: Wed, 19 May 2021 11:15:36 +0200
Subject: [PATCH 087/147] Update aea/test_tools/test_cases.py
Co-authored-by: David Minarsch
---
aea/test_tools/test_cases.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/aea/test_tools/test_cases.py b/aea/test_tools/test_cases.py
index 3a7ed74e38..045b2b0147 100644
--- a/aea/test_tools/test_cases.py
+++ b/aea/test_tools/test_cases.py
@@ -682,7 +682,7 @@ def generate_wealth(
Run from agent's directory.
:param ledger_api_id: ledger API ID.
- :param password: the password option.
+ :param password: the password.
:return: Result
"""
From 69d57cf8e60bfad787995d7c9a6291c95d7d975c Mon Sep 17 00:00:00 2001
From: Marco Favorito
Date: Wed, 19 May 2021 11:15:45 +0200
Subject: [PATCH 088/147] Update aea/test_tools/test_cases.py
Co-authored-by: David Minarsch
---
aea/test_tools/test_cases.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/aea/test_tools/test_cases.py b/aea/test_tools/test_cases.py
index 045b2b0147..3cbe5fa39b 100644
--- a/aea/test_tools/test_cases.py
+++ b/aea/test_tools/test_cases.py
@@ -591,7 +591,7 @@ def generate_private_key(
:param ledger_api_id: ledger API ID.
:param private_key_file: the private key file.
- :param password: the password option.
+ :param password: the password.
:return: Result
"""
From c28c99ad0db878ea35a2f89c813b455734438c27 Mon Sep 17 00:00:00 2001
From: ali
Date: Wed, 19 May 2021 10:21:37 +0100
Subject: [PATCH 089/147] feat: soef fixture skeleton
---
tests/common/docker_image.py | 52 ++++++++++++++++++++++++++++++++++++
tests/conftest.py | 17 ++++++++++++
2 files changed, 69 insertions(+)
diff --git a/tests/common/docker_image.py b/tests/common/docker_image.py
index 2c35b780de..5e716c6a37 100644
--- a/tests/common/docker_image.py
+++ b/tests/common/docker_image.py
@@ -337,6 +337,58 @@ def wait(self, max_attempts: int = 15, sleep_rate: float = 1.0) -> bool:
return False
+class SOEFDockerImage(DockerImage):
+ """Wrapper to SOEF Docker image."""
+
+ def __init__(
+ self,
+ client: DockerClient,
+ addr: str,
+ port: int = 9002,
+ ):
+ """
+ Initialize the SOEF Docker image.
+
+ :param client: the Docker client.
+ :param addr: the address.
+ :param port: the port.
+ """
+ super().__init__(client)
+ self._addr = addr
+ self._port = port
+
+ @property
+ def tag(self) -> str:
+ """Get the image tag."""
+ return "fetchai/soef:latest"
+
+ def _make_ports(self) -> Dict:
+ """Make ports dictionary for Docker."""
+ return {f"{self._port}/tcp": ("0.0.0.0", self._port)} # nosec
+
+ def create(self) -> Container:
+ """Create the container."""
+ container = self._client.containers.run(
+ self.tag,
+ detach=True,
+ ports=self._make_ports()
+ )
+ return container
+
+ def wait(self, max_attempts: int = 15, sleep_rate: float = 1.0) -> bool:
+ """Wait until the image is up."""
+ request = dict(jsonrpc=2.0, method="web3_clientVersion", params=[], id=1)
+ for i in range(max_attempts):
+ try:
+ response = requests.post(f"{self._addr}:{self._port}", json=request)
+ enforce(response.status_code == 200, "")
+ return True
+ except Exception:
+ logger.info(f"Attempt {i} failed. Retrying in {sleep_rate} seconds...")
+ time.sleep(sleep_rate)
+ return False
+
+
class FetchLedgerDockerImage(DockerImage):
"""Wrapper to Fetch ledger Docker image."""
diff --git a/tests/conftest.py b/tests/conftest.py
index 5f98fa6a19..33ed0f6ba2 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -109,6 +109,7 @@
FetchLedgerDockerImage,
GanacheDockerImage,
OEFSearchDockerImage,
+ SOEFDockerImage,
)
from tests.data.dummy_connection.connection import DummyConnection # type: ignore
@@ -730,6 +731,22 @@ def ganache(
yield from _launch_image(image, timeout=timeout, max_attempts=max_attempts)
+@pytest.mark.integration
+@pytest.fixture(scope="function")
+def soef(
+ soef_addr: str = "http://127.0.0.1",
+ soef_port: int = 9002,
+ timeout: float = 2.0,
+ max_attempts: int = 10,
+):
+ """Launch the Ganache image."""
+ client = docker.from_env()
+ image = SOEFDockerImage(
+ client, soef_addr, soef_port
+ )
+ yield from _launch_image(image, timeout=timeout, max_attempts=max_attempts)
+
+
@pytest.mark.integration
@pytest.mark.ledger
@pytest.fixture(scope="session")
From 02e313ddd8ae96eddd94f5c3120395093c2bbba3 Mon Sep 17 00:00:00 2001
From: James Riehl
Date: Thu, 20 May 2021 15:09:17 +0100
Subject: [PATCH 090/147] feat: upgrade oracle and oracle client contracts
---
.../contracts/oracle/build/oracle.wasm | Bin 193389 -> 196065 bytes
.../oracle_client/build/oracle_client.wasm | Bin 194437 -> 163649 bytes
.../contracts/oracle_client/contract.py | 3 ++-
.../contracts/oracle_client/contract.yaml | 2 +-
.../skills/simple_oracle_client/behaviours.py | 1 +
.../skills/simple_oracle_client/skill.yaml | 5 +++--
.../skills/simple_oracle_client/strategy.py | 6 ++++++
7 files changed, 13 insertions(+), 4 deletions(-)
mode change 100644 => 100755 packages/fetchai/contracts/oracle/build/oracle.wasm
mode change 100644 => 100755 packages/fetchai/contracts/oracle_client/build/oracle_client.wasm
diff --git a/packages/fetchai/contracts/oracle/build/oracle.wasm b/packages/fetchai/contracts/oracle/build/oracle.wasm
old mode 100644
new mode 100755
index 07de37f73706c1b4e58111d96aecb8accd21da49..8a40e1da153799dd62df68f4a543b1e469463304
GIT binary patch
literal 196065
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 NN75_>aS1=s^o94~c83XQQ5%JS}VO2(4UaL7cR
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