discover_runners: keep livepeer/node price_usd exact
I maintainer di solito rispondono entro 2 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 62/100
Direzione di ricerca
Start with request_json and get_json in src/livepeer_gateway/http.py, then discover_runners in discovery.py, which should pass parse_float=Decimal. Write the failing test first in tests/test_discovery.py, patching http._request_body with a 36-digit price_usd and an integer price, and assert price_usd equals Decimal and price stays int. Done when the test passes, other responses still return floats, and the Decimal price is accepted in _live_runner_price_info_from_json in live_runner.py.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Problem
livepeer/node now sends price_info.price_usd in runner discovery, and discover_runners does not return it as sent. The SDK rounds it to a float, so callers see a different price from the one the node advertises.
The orchestrator computes price_usd as an exact fraction, writes up to 36 decimal places and trims trailing zeros (orchestrator/registry.go#L238-L242). It serves the result from GET /discovery (orchestrator/http.go#L63). The signer passes the field through as a json.Number, so the digits are not changed there either (signer/service.go#L238). For example, a runner that registers at 0.01 USD/hour is advertised at 0.0000027777777777777777777777777777 USD per second.
discover_runners reads the body through get_json and request_json, which calls json.loads(raw) (http.py#L223-L224). That turns any JSON number with a fraction into a float, which holds about 16 significant digits:
>>> json.loads("0.0000027777777777777777777777777777")
2.777777777777778e-06
>>> json.loads("0.0000027777777777777777777777777777", parse_float=Decimal)
Decimal('0.0000027777777777777777777777777777')
price is unaffected: the node sends it in wei as a JSON integer, and json.loads keeps integers exact.
Change
The goal is parity: discover_runners should return the price exactly as the node advertised it.
-
Add a
parse_floatkeyword torequest_jsonandget_jsonand pass it tojson.loads(http.py#L201-L228,#L312-L321). It defaults toNone, which is alsojson.loads's default (float). Signer and runner responses also go throughrequest_json, and their callers expect floats, so they must not change.async def request_json( url: str, *, ..., timeout: float = 5.0, parse_float: Callable[[str], Any] | None = None, ) -> Any: ... return json.loads(raw, parse_float=parse_float) -
Pass
parse_float=Decimalindiscover_runnersonly (discovery.py#L161):data = await get_json(discovery_endpoint, headers=request_headers, parse_float=Decimal)discover_orchestratorsreads only addresses, so it can stay as it is.
The return type is still list[dict[str, Any]]. The value type of price_usd changes from float to Decimal, so add a line about it to the release notes.
Callers in this repo that need updating
_live_runner_price_info_from_json(live_runner.py#L1082-L1094) acceptspriceonly as anint,floatorstr. After this change, apricewith a fraction would arrive as aDecimal. The function would then returnNone, and the session would be reserved with nomax_price.- The node sends
priceas a wei integer today, so this does not happen yet. - Fix: add
Decimalto that check and toLiveRunnerPriceInfo.price(#L264-L267). _pad_runner_pricealready works throughDecimaland needs no change.
- The node sends
examples/select_runner.py#L86callsjson.dumps(runner.raw, indent=2). That raisesTypeError: Object of type Decimal is not JSON serializablefor any runner that hasprice_usd. Fix: passdefault=str.- The
_get_jsontest fake (tests/test_discovery.py#L102-L104) accepts onlyheaders. It needs aparse_floatparameter too.
Callers outside the SDK that serialize discovery entries, or that do arithmetic with price_usd as a float, need to handle Decimal, for example with str(value) or json.dumps(..., default=str).
Tests
Write each test first and check that it fails on main.
price_usdstays exact.- Patch
http._request_bodyto return a discovery body with the 36-digitprice_usdand an integerprice. Do not patchget_json: that would skipjson.loads. - Assert that
price_usd == Decimal("0.0000027777777777777777777777777777")and thatpriceis still anint. - On
main,price_usdis a float, which never equals thatDecimal.
- Patch
- Other responses still return floats.
request_jsonwith noparse_floatstill returns afloatfor a number with a fraction. - A
Decimalprice is accepted._live_runner_price_info_from_json({"price": Decimal("0.5"), ...})returns price info, notNone.
Not this
- Do not convert wei to USD in the SDK.
price_usdis the node's own figure. - Do not fill in a missing currency or unit. That is handled elsewhere (
_pad_runner_priceandcall_runner). - Do not change how JSON is parsed in every
request_jsoncall.
- Lingua principale
- Python
- Stelle
- 1
- Fork
- 10
- Merge medio
- 1g 9h
- PR unite (30g)
- 7
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di livepeer/livepeer-python-gateway
-
call_runner rejects a top-level JSON array, so a runner cannot pass one throughForse già presa @rickstaa l’ha presa 74 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
livepeer/livepeer-python-gateway#64 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Align pricing terminology: pixels_per_unit -> pricing_unit_size (track go-livepeer #3942)Forse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. ApertaImprovement
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 68/100
livepeer/livepeer-python-gateway#27 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
livepeer/livepeer-python-gateway#21 ·
I maintainer di solito rispondono entro 2 giorni
-
trickle_publisher: `_resolve_next_seq` fallback drops first video segment + logs noisy warningForse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 70/100
livepeer/livepeer-python-gateway#12 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
livepeer/livepeer-python-gateway#87 ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di livepeer/livepeer-python-gateway
Issue simili
-
ReadQwen3PaperTask5 rejects correct answers that differ only in order, case, or underscore formForse già presa @Kingpython123 l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 90/100
Tongyi-MAI/MobileWorld#72 ·
-
_threads/application: Update typing annotations using `pyupgrade --py311-plus`Forse già presa @gudnimg l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Health probes return 401 when authentication is enabled and the API is served under /orbForse già presa @fgogolli l’ha presa oggi. Apertaarea: api priority: p2 size: S type: bug
Difficoltà 2/5 Mezza giornata Idoneità per principianti 75/100
finos/open-resource-broker#704 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
BCDA-APS/polar-bits#93 ·
-
bug
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 90/100
GoogleCloudPlatform/gce-rescue#218 ·
I maintainer di solito rispondono entro 2 giorni