Skip to content

feat(api): add Content/VoteState/Beneficiary for condenser_api.get_content - #18

Merged
ety001 merged 1 commit into
masterfrom
feat/get-content
Aug 13, 2026
Merged

feat(api): add Content/VoteState/Beneficiary for condenser_api.get_content#18
ety001 merged 1 commit into
masterfrom
feat/get-content

Conversation

@ety001

@ety001 ety001 commented Aug 13, 2026

Copy link
Copy Markdown
Member

Summary

Add Content (the discussion object), VoteState (active_votes element), and Beneficiary to protocol/api, for steemdb-sync's comment rescanner (Batch 5). steemgosdk will consume this via a new GetContent wrapper (separate PR, depends on a new tag here).

⚠️ Spec correction — field types differ from the original requirement

The original spec assumed the share_type fields were always JSON strings ("实测都是 string"). Live testing against condenser_api.get_content showed they are int/string-mixed, so the struct had to be corrected before landing:

  • Within one response, active_votes[].rshares has both a JSON number (2125781185) and a JSON string ("221646137396") coexisting.
  • Top-level net_rshares/abs_rshares arrive as strings (large values), while total_vote_weight arrives as a number (small value).
  • steemd serializes share_type / int64 / uint64 as a JSON number within the int32 range and a JSON string beyond it.

Using a typed string field would fail to decode the number form (and vice versa) — the same class of bug as ExtendedAccount (a2cad55) and Manabar.CurrentMana (b1d22f9). So all 10 such fields use json.RawMessage, matching the established pattern.

Verified against three sources: live get_content responses (old + recent post), steemd C++ source (condenser_api.hpp / tags_api.hpp / types.hpp), and jussi upstream routing (get_content is not rewritten).

Other corrections vs the spec

  • post_idid (the chain emits id, not post_id).
  • Added 13 fields the spec omitted: body_length, reward_weight, percent_steem_dollars, root_author, root_permlink, allow_votes/allow_replies/allow_curation_rewards, beneficiaries, reblogged_by, first_reblogged_by/first_reblogged_on (pointers, optional on chain), id.

Field type strategy (matches ExtendedAccount)

Category Go type Reason
asset strings ("100.000 SBD") string always string; consumer parses via ParseAsset
ISO timestamps string always string
share_type / int64 / uint64 (10 fields) json.RawMessage int/string-mixed on chain
small int (id/depth/children/net_votes/etc.) int always a small JSON number
allow_* bool always JSON true/false
percentages (uint16) int always a small JSON number
beneficiaries []Beneficiary {account,weight} array

Tests

go build ./... + go test ./... all green; existing tests unaffected.

  • TestUnmarshal_Content_FullFixture — recent post fixture; covers RawMessage string form (net_rshares) + number form (total_vote_weight), and mixed active_votes[].rshares forms within one response.
  • TestUnmarshal_Content_OldPost — legacy post; covers the other half (small values as numbers, plus weight as string / rshares as number).

After merge

This needs a v0.0.30 tag so steemgosdk can consume it.

…ntent

Add Content (the discussion object returned by condenser_api.get_content),
VoteState (active_votes element), and Beneficiary to protocol/api, for
steemdb-sync's comment rescanner.

Field types match the on-chain JSON exactly (verified against live
get_content responses + steemd source):
  - share_type / large-int group (net_rshares, abs_rshares, vote_rshares,
    children_abs_rshares, author_rewards, author_reputation,
    total_vote_weight) and active_votes[].weight/rshares/reputation use
    json.RawMessage: steemd serializes these inconsistently as JSON number
    (within int32 range) or JSON string (larger), with both forms coexisting
    within a single response. A typed field would fail to decode on one or
    the other (same class of bug as ExtendedAccount/Manabar, b1d22f9).
  - assets and timestamps stay string; id/depth/children/net_votes/etc.
    stay int; allow_* stay bool.
  - first_reblogged_by/on are pointers (optional on chain -> nil when absent).

The original spec draft assumed these share_type fields were always strings;
live testing showed they are int/string-mixed, so json.RawMessage is required.

Fixes the post_id field name (chain emits id, not post_id) and adds 13
fields the spec draft omitted (body_length, reward_weight,
percent_steem_dollars, root_author, root_permlink, allow_votes/replies/
curation_rewards, beneficiaries, reblogged_by, first_reblogged_by/on, id).
@ety001
ety001 merged commit 2d83e30 into master Aug 13, 2026
3 checks passed
@ety001
ety001 deleted the feat/get-content branch August 13, 2026 14:26
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.

1 participant