Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ RUN apt-get update && \
librocksdb-dev \
libsnappy-dev \
libunwind8-dev \
jq \
&& rm -rf /var/lib/apt/lists/*

34 changes: 33 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,41 @@ jobs:
rm -f ./out/Plugins/TokensTracker/RpcServer.dll
rm -f ./out/Plugins/StateService/RpcServer.dll
- name: Install dependencies
run: sudo apt-get install -y libleveldb-dev expect
run: sudo apt-get install -y libleveldb-dev expect jq
- name: Run tests with expect
run: expect ./.github/workflows/test-neo-cli-plugins.expect
- name: Start neo-cli with plugins
run: |
dotnet out/neo-cli.dll &
NEO_PID=$!
echo "NEO_PID=$NEO_PID" >> $GITHUB_ENV

echo "Waiting for neo-cli RPC endpoint to become ready..."
ATTEMPTS=0
MAX_ATTEMPTS=30
SLEEP_SECONDS=2
until curl -s -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"getversion","params":[],"id":1}' \
http://localhost:10332 | jq -e '.jsonrpc' >/dev/null 2>&1; do
ATTEMPTS=$((ATTEMPTS+1))
if [ "$ATTEMPTS" -ge "$MAX_ATTEMPTS" ]; then
echo "neo-cli RPC endpoint did not become ready in time"
exit 1
fi
sleep "$SLEEP_SECONDS"
done
echo "neo-cli RPC endpoint is ready."
- name: Test RPC calls
run: |
chmod +x ./.github/workflows/test-rpc-calls.sh
./.github/workflows/test-rpc-calls.sh
- name: Stop neo-cli
if: always()
run: |
if [ -n "$NEO_PID" ]; then
kill "$NEO_PID" || true
wait "$NEO_PID" || true
fi

Release:
if: github.ref == 'refs/heads/master-n3' && github.repository == 'neo-project/neo-node'
Expand Down
74 changes: 74 additions & 0 deletions .github/workflows/test-rpc-calls.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/bin/bash

# Test RPC server calls
RPC_URL="http://127.0.0.1:10332"

echo "Testing RPC server consistency..."

# Test 1: getversion
echo "Testing getversion..."
response=$(curl -s -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "id": 1, "method": "getversion"}' $RPC_URL)
if [[ $? -ne 0 ]]; then
echo "Failed to call getversion"
Comment on lines +8 to +12

Copilot AI Mar 22, 2026

Copy link

Choose a reason for hiding this comment

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

There is a lot of repeated curl + jq boilerplate across the individual RPC tests, which will make it harder to extend this script with more plugin RPC checks later. Consider introducing a small helper function (e.g., rpc_call method id) that performs the POST + .error/.result validation once and returns the parsed JSON for method-specific assertions.

Copilot uses AI. Check for mistakes.
exit 1
fi
echo "getversion response: $response"

# Check if response contains expected fields
if ! echo "$response" | jq -e '.result.tcpport' > /dev/null; then
echo "getversion response missing tcpport"
exit 1
fi
Comment on lines +10 to +21

Copilot AI Mar 22, 2026

Copy link

Choose a reason for hiding this comment

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

The script only checks curl's exit code, but JSON-RPC failures typically come back as HTTP 200 with an .error object (curl still exits 0). This can lead to misleading failures (or passing checks against an empty/incorrect .result). Consider asserting .error == null (and .result exists) for each call before validating fields like .result.tcpport.

Copilot uses AI. Check for mistakes.

# Test 2: getbestblockhash
echo "Testing getbestblockhash..."
response=$(curl -s -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "id": 2, "method": "getbestblockhash"}' $RPC_URL)
Comment on lines +10 to +25

Copilot AI Mar 22, 2026

Copy link

Choose a reason for hiding this comment

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

All curl invocations use -s without timeouts/retries. If the node is slow to start or the port is unreachable, the job can hang for a long time and/or fail flakily. Consider adding -sS plus bounded timeouts (e.g., connect/max time) and retry/poll logic (or a dedicated readiness loop before the tests).

Copilot uses AI. Check for mistakes.
if [[ $? -ne 0 ]]; then
echo "Failed to call getbestblockhash"
exit 1
fi
echo "getbestblockhash response: $response"

# Should be a string hash
if ! echo "$response" | jq -e '.result | type == "string"' > /dev/null; then
echo "getbestblockhash response not a string"
exit 1
fi

# Test 3: getblockcount
echo "Testing getblockcount..."
response=$(curl -s -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "id": 3, "method": "getblockcount"}' $RPC_URL)
if [[ $? -ne 0 ]]; then
echo "Failed to call getblockcount"
exit 1
fi
echo "getblockcount response: $response"

# Should be a number
if ! echo "$response" | jq -e '.result | type == "number"' > /dev/null; then
echo "getblockcount response not a number"
exit 1
fi

# Test 4: listplugins
echo "Testing listplugins..."
response=$(curl -s -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "id": 4, "method": "listplugins"}' $RPC_URL)
if [[ $? -ne 0 ]]; then
echo "Failed to call listplugins"
exit 1
fi
echo "listplugins response: $response"

# Should be an array
if ! echo "$response" | jq -e '.result | type == "array"' > /dev/null; then
echo "listplugins response not an array"
exit 1
fi

# Check if RpcServer is in the list
if ! echo "$response" | jq -e '.result[] | select(.name == "RpcServer")' > /dev/null; then
echo "RpcServer not found in plugins list"
exit 1
fi

echo "All RPC tests passed!"
Loading