Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Feb 3, 2026

High Level Overview of Change

The Peer Crawler API returns port as a string for outbound peers but as an integer for inbound peers. This fixes the inconsistency by making port always return as an integer.

Context of Change

Bug introduced in the original peer crawler implementation (PR #1017, RIPD-866). Outbound peers used std::to_string() on the port while inbound peers assigned the numeric value directly.

Also moves inline string literals "active", "in", "out" to jss.h per repo conventions.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Documentation update

API Impact

  • Public API: Breaking change (in general, breaking changes should only impact the next api_version)

Note: This affects the special peer-port API, not the standard RPC API, so API versioning does not apply.

Before / After

Before: Outbound peers return port as string

{"active": [{"type": "out", "port": "51235", ...}]}

After: All peers return port as integer

{"active": [{"type": "out", "port": 51235, ...}]}

Test Plan

Manual testing is recommended for this change. Call the peer crawler on a server that has both incoming and outgoing peers and verify:

  • The port field is returned as an integer for both inbound and outbound peers
  • The type field uses the expected "in"/"out" values
Original prompt

This section details on the original issue you should resolve

<issue_title>Peer crawler port field type inconsistency</issue_title>
<issue_description>## Issue Description
The "Peer Crawler" special API method reports the port of peers as either an integer or a string depending on if the connection is inbound/outbound. This was probably an oversight in the original PR, and the field should be consistently the same type.

Steps to Reproduce

Call the peer crawler on a server that has both incoming and outgoing peers and check the response.

Expected Result

The port fields in the overlay.active[] array members should all be the same type, probably Number. Port numbers should always fit in any reasonable primitive that JSON numbers can be deserialized into.

Solution

Always make port a Number type. Note, this is (kind of) an API change, but to a special peer-port-API method and not to the standard API, so API versioning concerns do not apply.

Environment

rippled 1.2.1 through 2.1.x

Related issues

</issue_description>

<agent_instructions>The relevant file will be src/xrpld/overlay/detail/OverlayImpl.cpp - the getOverlayInfo method.
Please also move the "active", "in", and "out" strings to jss.h to follow repo norms and update the API changelog with a note about this change.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Fix peer crawler port field type inconsistency Fix peer crawler port field type inconsistency Feb 3, 2026
Copilot AI requested a review from mvadari February 3, 2026 15:10
@mvadari mvadari added the DraftRunCI Normally CI does not run on draft PRs. This opts in. label Feb 3, 2026
@mvadari
Copy link
Collaborator

mvadari commented Feb 3, 2026

@copilot please add tests (or modify tests if they already exist)

Copy link
Contributor Author

Copilot AI commented Feb 3, 2026

@copilot please add tests (or modify tests if they already exist)

Added OverlayInfo_test.cpp in commit 99d7ba4 with tests that verify:

  1. port field is consistently an integer for both inbound and outbound peers
  2. type field values use the expected "in"/"out" values

@mvadari
Copy link
Collaborator

mvadari commented Feb 3, 2026

@copilot tests appear to be failing, please fix

FAILED: CMakeFiles/xrpld.dir/src/test/overlay/OverlayInfo_test.cpp.o 
/usr/local/bin/ccache /usr/bin/clang++-16 -DBOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS -DBOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT -DBOOST_BEAST_ALLOW_DEPRECATED -DBOOST_CONTAINER_FWD_BAD_DEQUE -DBOOST_COROUTINES_NO_DEPRECATION_WARNING -DBOOST_FILESYSTEM_DEPRECATED -DCARES_STATICLIB -DDATE_HEADER_ONLY -DDEBUG -DENABLE_TESTS -DENABLE_VOIDSTAR -DGIT_BRANCH=\"HEAD\" -DGIT_COMMIT_HASH=\"9915c380ff4996654c7d4270483185f6dd0aa2eb\" -DHAS_UNCAUGHT_EXCEPTIONS=1 -DOPENSSL_SUPPRESS_DEPRECATED -DTRUNCATED_THREAD_NAME_LOGS -DUNIT_TEST_REFERENCE_FEE=10 -DXRPL_ROCKSDB_AVAILABLE=1 -DXRPL_RUNNING_IN_CI -D_DEBUG -I/__w/rippled/rippled/src -I/__w/rippled/rippled/external/antithesis-sdk -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.basics -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.beast -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.core -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.json -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.protocol -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.crypto -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.resource -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.server -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.nodestore -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.shamap -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.net -I/__w/rippled/rippled/build/modules/xrpl.libxrpl.ledger -isystem /root/.conan2/p/boost46122fa8042d3/p/include -isystem /root/.conan2/p/ed255b5e3c1965efe4/p/include -isystem /root/.conan2/p/opens2e78beba79d93/p/include -isystem /root/.conan2/p/zlib280ee6cf3cf0b/p/include -isystem /root/.conan2/p/lz4f242d9b7b256c/p/include -isystem /root/.conan2/p/secp2e310c44015e89/p/include -isystem /root/.conan2/p/soci141b95f26136d/p/include -isystem /root/.conan2/p/sqlita0472a3ed6657/p/include -isystem /root/.conan2/p/rocksb0362d8c06cdb/p/include -isystem /root/.conan2/p/nudb6dfa0f8122cb9/p/include -isystem /root/.conan2/p/abseifa048edf5c264/p/include -isystem /root/.conan2/p/dated9120624eb414/p/include -isystem /root/.conan2/p/libara472d148dee68/p/include -isystem /__w/rippled/rippled/build/pb-xrpl.libpb -isystem /__w/rippled/rippled/build/pb-xrpl.libpb/xrpl/proto -isystem /root/.conan2/p/protoa5b789f6fe11c/p/include -isystem /root/.conan2/p/grpc9625f0b03178b/p/include -isystem /root/.conan2/p/xxhas86eebcf4919b1/p/include -stdlib=libstdc++ -g -std=c++20 -fPIE -Wno-unknown-warning-option -fsanitize-coverage=trace-pc-guard -Wall -Wdeprecated -Wno-deprecated-declarations -Wextra -Wno-unused-parameter -Werror -fstack-protector -Wno-sign-compare -Wno-unused-but-set-variable -MD -MT CMakeFiles/xrpld.dir/src/test/overlay/OverlayInfo_test.cpp.o -MF CMakeFiles/xrpld.dir/src/test/overlay/OverlayInfo_test.cpp.o.d -o CMakeFiles/xrpld.dir/src/test/overlay/OverlayInfo_test.cpp.o -c /__w/rippled/rippled/src/test/overlay/OverlayInfo_test.cpp
/__w/rippled/rippled/src/test/overlay/OverlayInfo_test.cpp:103:15: error: no member named 'set_listening_port' in 'xrpl::PeerFinder::Slot'
        slot->set_listening_port(listeningPort);
        ~~~~~~^
/__w/rippled/rippled/src/test/overlay/OverlayInfo_test.cpp:171:36: error: 'getOverlayInfo' is a private member of 'xrpl::OverlayImpl'
        auto overlayInfo = overlay.getOverlayInfo();
                                   ^
/__w/rippled/rippled/src/xrpld/overlay/detail/OverlayImpl.h:468:5: note: declared private here
    getOverlayInfo();
    ^
/__w/rippled/rippled/src/test/overlay/OverlayInfo_test.cpp:223:36: error: 'getOverlayInfo' is a private member of 'xrpl::OverlayImpl'
        auto overlayInfo = overlay.getOverlayInfo();
                                   ^
/__w/rippled/rippled/src/xrpld/overlay/detail/OverlayImpl.h:468:5: note: declared private here
    getOverlayInfo();
    ^
In file included from /__w/rippled/rippled/src/test/overlay/OverlayInfo_test.cpp:1:
In file included from /__w/rippled/rippled/src/test/jtx.h:6:
In file included from /__w/rippled/rippled/src/test/jtx/AMM.h:4:
In file included from /__w/rippled/rippled/src/test/jtx/Account.h:4:
In file included from /__w/rippled/rippled/build/modules/xrpl.libxrpl.beast/xrpl/beast/hash/uhash.h:4:
In file included from /__w/rippled/rippled/build/modules/xrpl.libxrpl.beast/xrpl/beast/hash/hash_append.h:4:
In file included from /root/.conan2/p/boost46122fa8042d3/p/include/boost/container/flat_set.hpp:29:
In file included from /root/.conan2/p/boost46122fa8042d3/p/include/boost/container/detail/flat_tree.hpp:29:
In file included from /root/.conan2/p/boost46122fa8042d3/p/include/boost/container/vector.hpp:32:
In file included from /root/.conan2/p/boost46122fa8042d3/p/include/boost/container/detail/advanced_insert_int.hpp:28:
In file included from /root/.conan2/p/boost46122fa8042d3/p/include/boost/container/detail/copy_move_algo.hpp:24:
In file included from /root/.conan2/p/boost46122fa8042d3/p/include/boost/container/detail/iterator.hpp:24:
In file included from /root/.conan2/p/boost46122fa8042d3/p/include/boost/intrusive/detail/iterator.hpp:27:
In file included from /root/.conan2/p/boost46122fa8042d3/p/include/boost/move/detail/iterator_traits.hpp:27:
In file included from /usr/bin/../lib/gcc/aarch64-linux-gnu/12/../../../../include/c++/12/iterator:63:
In file included from /usr/bin/../lib/gcc/aarch64-linux-gnu/12/../../../../include/c++/12/bits/stl_iterator.h:85:
/usr/bin/../lib/gcc/aarch64-linux-gnu/12/../../../../include/c++/12/bits/stl_construct.h:115:4: error: no matching function for call to 'construct_at'
          std::construct_at(__p, std::forward<_Args>(__args)...);
          ^~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/aarch64-linux-gnu/12/../../../../include/c++/12/bits/alloc_traits.h:635:9: note: in instantiation of function template specialization 'std::_Construct<xrpl::test::OverlayInfo_test::PeerTest, xrpl::Application &, std::pair<std::shared_ptr<xrpl::PeerFinder::Slot>, xrpl::PeerFinder::Result> &, boost::beast::http::message<true, boost::beast::http::basic_dynamic_body<boost::beast::basic_multi_buffer<std::allocator<char>>>>, xrpl::PublicKey &, std::pair<unsigned short, unsigned short> &, xrpl::Resource::Consumer &, std::unique_ptr<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp>>>, xrpl::OverlayImpl &>' requested here
        { std::_Construct(__p, std::forward<_Args>(__args)...); }
               ^
/usr/bin/../lib/gcc/aarch64-linux-gnu/12/../../../../include/c++/12/bits/shared_ptr_base.h:604:30: note: in instantiation of function template specialization 'std::allocator_traits<std::allocator<void>>::construct<xrpl::test::OverlayInfo_test::PeerTest, xrpl::Application &, std::pair<std::shared_ptr<xrpl::PeerFinder::Slot>, xrpl::PeerFinder::Result> &, boost::beast::http::message<true, boost::beast::http::basic_dynamic_body<boost::beast::basic_multi_buffer<std::allocator<char>>>>, xrpl::PublicKey &, std::pair<unsigned short, unsigned short> &, xrpl::Resource::Consumer &, std::unique_ptr<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp>>>, xrpl::OverlayImpl &>' requested here
          allocator_traits<_Alloc>::construct(__a, _M_ptr(),
                                    ^
/usr/bin/../lib/gcc/aarch64-linux-gnu/12/../../../../include/c++/12/bits/shared_ptr_base.h:972:6: note: in instantiation of function template specialization 'std::_Sp_counted_ptr_inplace<xrpl::test::OverlayInfo_test::PeerTest, std::allocator<void>, __gnu_cxx::_S_atomic>::_Sp_counted_ptr_inplace<xrpl::Application &, std::pair<std::shared_ptr<xrpl::PeerFinder::Slot>, xrpl::PeerFinder::Result> &, boost::beast::http::message<true, boost::beast::http::basic_dynamic_body<boost::beast::basic_multi_buffer<std::allocator<char>>>>, xrpl::PublicKey &, std::pair<unsigned short, unsigned short> &, xrpl::Resource::Consumer &, std::unique_ptr<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp>>>, xrpl::OverlayImpl &>' requested here
            _Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
            ^
/usr/bin/../lib/gcc/aarch64-linux-gnu/12/../../../../include/c++/12/bits/shared_ptr_base.h:1712:14: note: in instantiation of function template specialization 'std::__shared_count<>::__shared_count<xrpl::test::OverlayInfo_test::PeerTest, std::allocator<void>, xrpl::Application &, std::pair<std::shared_ptr<xrpl::PeerFinder::Slot>, xrpl::PeerFinder::Result> &, boost::beast::http::message<true, boost::beast::http::basic_dynamic_body<boost::beast::basic_multi_buffer<std::allocator<char>>>>, xrpl::PublicKey &, std::pair<unsigned short, unsigned short> &, xrpl::Resource::Consumer &, std::unique_ptr<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp>>>, xrpl::OverlayImpl &>' requested here
        : _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
                    ^
/usr/bin/../lib/gcc/aarch64-linux-gnu/12/../../../../include/c++/12/bits/shared_ptr.h:464:4: note: in instantiation of function template specialization 'std::__shared_ptr<xrpl::test::OverlayInfo_test::PeerTest>::__shared_ptr<std::allocator<void>, xrpl::Application &, std::pair<std::shared_ptr<xrpl::PeerFinder::Slot>, xrpl::PeerFinder::Result> &, boost::beast::http::message<true, boost::beast::http::basic_dynamic_body<boost::beast::basic_multi_buffer<std::allocator<char>>>>, xrpl::PublicKey &, std::pair<unsigned short, unsigned short> &, xrpl::Resource::Consumer &, std::unique_ptr<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp>>>, xrpl::OverlayImpl &>' requested here
        : __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
          ^
/usr/bin/../lib/gcc/aarch64-linux-gnu/12/../../../../include/c++/12/bits/shared_ptr.h:1009:14: note: in instantiation of function template specialization 'std::shared_ptr<xrpl::test::OverlayInfo_test::PeerTest>::shared_ptr<std::allocator<void>, xrpl::Application &, std::pair<std::shared_ptr<xrpl::PeerFinder::Slot>, xrpl::PeerFinder::Result> &, boost::beast::http::message<true, boost::beast::http::basic_dynamic_body<boost::beast::basic_multi_buffer<std::allocator<char>>>>, xrpl::PublicKey &, std::pair<unsigned short, unsigned short> &, xrpl::Resource::Consumer &, std::unique_ptr<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp>>>, xrpl::OverlayImpl &>' requested here
      return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
             ^
/__w/rippled/rippled/src/test/overlay/OverlayInfo_test.cpp:136:26: note: in instantiation of function template specialization 'std::make_shared<xrpl::test::OverlayInfo_test::PeerTest, xrpl::Application &, std::pair<std::shared_ptr<xrpl::PeerFinder::Slot>, xrpl::PeerFinder::Result> &, boost::beast::http::message<true, boost::beast::http::basic_dynamic_body<boost::beast::basic_multi_buffer<std::allocator<char>>>>, xrpl::PublicKey &, std::pair<unsigned short, unsigned short> &, xrpl::Resource::Consumer &, std::unique_ptr<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp>>>, xrpl::OverlayImpl &>' requested here
        auto peer = std::make_shared<PeerTest>(
                         ^
/usr/bin/../lib/gcc/aarch64-linux-gnu/12/../../../../include/c++/12/bits/stl_construct.h:94:5: note: candidate template ignored: substitution failure [with _Tp = xrpl::test::OverlayInfo_test::PeerTest, _Args = <xrpl::Application &, std::pair<std::shared_ptr<xrpl::PeerFinder::Slot>, xrpl::PeerFinder::Result> &, boost::beast::http::message<true, boost::beast::http::basic_dynamic_body<boost::beast::basic_multi_buffer<std::allocator<char>>>>, xrpl::PublicKey &, std::pair<unsigned short, unsigned short> &, xrpl::Resource::Consumer &, std::unique_ptr<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp>>>, xrpl::OverlayImpl &>]: no matching constructor for initialization of 'xrpl::test::OverlayInfo_test::PeerTest'
    construct_at(_Tp* __location, _Args&&... __args)
    ^
/usr/bin/../lib/gcc/aarch64-linux-gnu/12/../../../../include/c++/12/bits/stl_construct.h:119:25: error: no matching constructor for initialization of 'xrpl::test::OverlayInfo_test::PeerTest'
      ::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
                        ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/__w/rippled/rippled/src/test/overlay/OverlayInfo_test.cpp:36:9: note: candidate constructor not viable: no known conversion from 'std::pair<std::shared_ptr<xrpl::PeerFinder::Slot>, xrpl::PeerFinder::Result>' to 'const std::shared_ptr<PeerFinder::Slot>' for 2nd argument
        PeerTest(
        ^
/__w/rippled/rippled/src/test/overlay/OverlayInfo_test.cpp:33:11: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 8 were provided
    class PeerTest : public PeerImp
          ^
5 errors generated.

Copy link
Contributor Author

Copilot AI commented Feb 3, 2026

@copilot tests appear to be failing, please fix

FAILED: CMakeFiles/xrpld.dir/src/test/overlay/OverlayInfo_test.cpp.o 

...

Fixed in commit f089cff:

  1. Added friend class test::OverlayInfo_test; declaration in OverlayImpl.h to allow test access to private getOverlayInfo()
  2. Changed slot->set_listening_port() to cast to SlotImp first using std::dynamic_pointer_cast, since set_listening_port() is only available on the implementation class, not the base Slot interface

@mvadari
Copy link
Collaborator

mvadari commented Feb 3, 2026

@copilot actually, just pull out the tests - they seem to be more of a headache than they're worth for such a small change. We can test manually.

Copy link
Contributor Author

Copilot AI commented Feb 3, 2026

@copilot actually, just pull out the tests - they seem to be more of a headache than they're worth for such a small change. We can test manually.

Removed the test file and reverted the friend declaration in commit 28a1796.

@mvadari mvadari marked this pull request as ready for review February 3, 2026 16:12
@mvadari mvadari requested review from a team and Copilot February 3, 2026 16:12
@mvadari mvadari removed the DraftRunCI Normally CI does not run on draft PRs. This opts in. label Feb 3, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a type inconsistency in the Peer Crawler /crawl overlay response by ensuring overlay.active[].port is always emitted as a JSON integer (previously a string for outbound peers).

Changes:

  • Update /crawl overlay serialization so outbound peers’ port is emitted as a number (consistent with inbound).
  • Replace inline "active", "in", and "out" literals with jss constants.
  • Document the behavior change in API-CHANGELOG.md.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/xrpld/overlay/detail/OverlayImpl.cpp Emits outbound port as an integer and uses jss::active / jss::in / jss::out.
include/xrpl/protocol/jss.h Adds jss::active, jss::in, and jss::out tokens.
API-CHANGELOG.md Notes the Peer Crawler port type consistency change under 3.1.0.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

API-CHANGELOG.md Outdated
Comment on lines 33 to 34
### Bugfixes in 3.1.0

Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changelog sectioning is inconsistent: this file uses headings like "Additions in X.Y.Z" or "Additions and bugfixes in X.Y.Z" elsewhere, but "### Bugfixes in 3.1.0" appears to be the only standalone bugfix heading. Consider merging this entry into the existing 3.1.0 heading (e.g., rename to "Additions and bugfixes in 3.1.0" or include the bullet under an existing heading) to keep the document structure consistent.

Copilot uses AI. Check for mistakes.
API-CHANGELOG.md Outdated

### Bugfixes in 3.1.0

- Peer Crawler: The `port` field in `overlay.active[]` now consistently returns an integer instead of a string for outbound peers.
Copy link

Copilot AI Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new changelog bullet doesn’t include a PR reference, while most other entries include a link like "(#NNNN)". Please add the relevant PR number/link for traceability.

Suggested change
- Peer Crawler: The `port` field in `overlay.active[]` now consistently returns an integer instead of a string for outbound peers.
- Peer Crawler: The `port` field in `overlay.active[]` now consistently returns an integer instead of a string for outbound peers. ([#6156](https://github.com/XRPLF/rippled/pull/6156))

Copilot uses AI. Check for mistakes.
Copilot AI and others added 2 commits February 3, 2026 11:21
- Change outbound peer port from string to integer in getOverlayInfo()
- Add "active", "in", "out" JSS constants to jss.h
- Update API-CHANGELOG.md with bugfix note

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
@mvadari mvadari force-pushed the copilot/fix-peer-crawler-port-type branch from 28a1796 to 42f6b94 Compare February 3, 2026 16:21
@mvadari mvadari force-pushed the copilot/fix-peer-crawler-port-type branch from 42f6b94 to aea548b Compare February 3, 2026 16:37
@codecov
Copy link

codecov bot commented Feb 3, 2026

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.9%. Comparing base (677758b) to head (96f512e).
⚠️ Report is 1 commits behind head on develop.

Files with missing lines Patch % Lines
src/xrpld/overlay/detail/OverlayImpl.cpp 0.0% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##           develop   #6318   +/-   ##
=======================================
  Coverage     79.9%   79.9%           
=======================================
  Files          840     840           
  Lines        65483   65483           
  Branches      7255    7252    -3     
=======================================
+ Hits         52311   52315    +4     
+ Misses       13172   13168    -4     
Files with missing lines Coverage Δ
src/xrpld/overlay/detail/OverlayImpl.cpp 32.9% <0.0%> (ø)

... and 3 files with indirect coverage changes

Impacted file tree graph

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Peer crawler port field type inconsistency

2 participants