Skip to content

Commit 521b69a

Browse files
test: add spec-shape tests for getVersionInfo and getFeeStats
Cover the wire format of real stellar-rpc (protocol 22): getVersionInfo returns exactly version/commitHash/buildTimestamp/captiveCoreVersion/ protocolVersion with protocolVersion as a JSON number, and getFeeStats returns both FeeDistribution objects (fee values and transactionCount as decimal strings, ledgerCount as a number) plus a live latestLedger number. Both methods take no parameters. The tests currently fail with -32601 since neither method is implemented yet.
1 parent 8f392c5 commit 521b69a

1 file changed

Lines changed: 95 additions & 0 deletions

File tree

src/tests/integration/test_server.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import importlib.metadata
34
import json
45
import shutil
56
import socket
@@ -498,3 +499,97 @@ def builder() -> TransactionBuilder:
498499

499500
# All four transactions, including the non-Void invocation, advanced the ledger.
500501
assert _rpc(server.port(), 'getLatestLedger', {})['result']['sequence'] == 4
502+
503+
504+
def test_get_version_info(server: StellarRpcServer) -> None:
505+
"""getVersionInfo returns exactly the five spec fields with the right JSON types.
506+
507+
Real stellar-rpc (protocol 22+) emits camelCase keys only; the deprecated snake_case
508+
aliases (``commit_hash``, ...) were removed, so an exact key-set check covers both the
509+
required fields and the absence of the legacy ones. ``protocolVersion`` is a Go uint32,
510+
i.e. a JSON number, not a string.
511+
"""
512+
resp = _rpc(server.port(), 'getVersionInfo', {})
513+
assert 'error' not in resp, resp
514+
result = resp['result']
515+
516+
assert set(result) == {'version', 'commitHash', 'buildTimestamp', 'captiveCoreVersion', 'protocolVersion'}
517+
# komet-node reports its own package version as the RPC server version.
518+
assert result['version'] == importlib.metadata.version('komet-node')
519+
assert type(result['commitHash']) is str
520+
assert type(result['buildTimestamp']) is str
521+
assert type(result['captiveCoreVersion']) is str
522+
assert type(result['protocolVersion']) is int # `is int` also rejects booleans
523+
assert result['protocolVersion'] == 22
524+
525+
526+
def test_get_version_info_accepts_omitted_params(server: StellarRpcServer) -> None:
527+
"""getVersionInfo takes no parameters; a request without a params member must succeed."""
528+
resp = _post(server.port(), b'{"jsonrpc": "2.0", "id": 1, "method": "getVersionInfo"}')
529+
assert 'error' not in resp, resp
530+
assert resp['result']['protocolVersion'] == 22
531+
532+
533+
# Every FeeDistribution field except ledgerCount is an unsigned integer serialised with Go's
534+
# `,string` option, i.e. a JSON string holding a decimal number (see the getFeeStats spec
535+
# example: `"transactionCount": "10"` but `"ledgerCount": 50`).
536+
_FEE_DISTRIBUTION_STRING_FIELDS = (
537+
'max',
538+
'min',
539+
'mode',
540+
'p10',
541+
'p20',
542+
'p30',
543+
'p40',
544+
'p50',
545+
'p60',
546+
'p70',
547+
'p80',
548+
'p90',
549+
'p95',
550+
'p99',
551+
'transactionCount',
552+
)
553+
554+
555+
def _assert_fee_distribution(dist: dict[str, Any]) -> None:
556+
"""Check one FeeDistribution object against the stellar-rpc wire format."""
557+
assert set(dist) == {*_FEE_DISTRIBUTION_STRING_FIELDS, 'ledgerCount'}
558+
for field in _FEE_DISTRIBUTION_STRING_FIELDS:
559+
value = dist[field]
560+
assert type(value) is str, f'{field} must be a JSON string, got {type(value).__name__}'
561+
assert value.isdigit(), f'{field} must hold a decimal number, got {value!r}'
562+
assert type(dist['ledgerCount']) is int, 'ledgerCount must be a JSON number'
563+
# The distribution must at least be internally consistent.
564+
assert int(dist['min']) <= int(dist['p50']) <= int(dist['max'])
565+
566+
567+
def test_get_fee_stats(server: StellarRpcServer) -> None:
568+
"""getFeeStats returns both fee distributions and latestLedger with the right JSON types."""
569+
resp = _rpc(server.port(), 'getFeeStats', {})
570+
assert 'error' not in resp, resp
571+
result = resp['result']
572+
573+
assert set(result) == {'sorobanInclusionFee', 'inclusionFee', 'latestLedger'}
574+
_assert_fee_distribution(result['sorobanInclusionFee'])
575+
_assert_fee_distribution(result['inclusionFee'])
576+
assert type(result['latestLedger']) is int # a JSON number, and 0 on a fresh chain
577+
assert result['latestLedger'] == 0
578+
579+
580+
def test_get_fee_stats_latest_ledger_tracks_chain(server: StellarRpcServer) -> None:
581+
"""getFeeStats reports the live ledger sequence, not a constant."""
582+
keypair = Keypair.random()
583+
account = Account(keypair.public_key, sequence=0)
584+
envelope = (
585+
TransactionBuilder(account, Network.TESTNET_NETWORK_PASSPHRASE)
586+
.append_create_account_op(destination=keypair.public_key, starting_balance='1000')
587+
.set_timeout(30)
588+
.build()
589+
)
590+
envelope.sign(keypair)
591+
assert _rpc(server.port(), 'sendTransaction', {'transaction': envelope.to_xdr()})['result']['status'] == 'PENDING'
592+
593+
resp = _rpc(server.port(), 'getFeeStats', {})
594+
assert 'error' not in resp, resp
595+
assert resp['result']['latestLedger'] == 1

0 commit comments

Comments
 (0)