Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Hesiod (class HS) metadata resolver #102

Merged
merged 17 commits into from
Nov 11, 2022

Conversation

pinheadmz
Copy link
Member

@pinheadmz pinheadmz commented Oct 20, 2022

Built on top of #101 waiting for review and merge

See original idea in handshake-org/hsd#443

API schema

The HS API can be thought of like a single JSON object:

.: {
  hnsd: {
    chain: {
      tip: {
        hash:   `32 byte hex string`,
        height: `unsigned int`,
        time:   `unsigned int`
      },
      synced:   `boolean`,
      progress: `float`
    },
    pool: {
      size:     `unsigned int`,
      [id].peers: [
        {
          host:  `string`,
          agent: `string`,
          headers `unsigned int`,
          proofs: `unsigned int`,
          state: `string`
        }
      ]
    }
  }
}

The object properties and sub-objects are addressed like a sort of backwards JSON notation, with an implied "wildcard" (*) prepended to the query string. So querying sub.domain. is equivalent to querying *.sub.domain and all the data at or below that level will be returned.

Examples

Retrieve the entire object:

$ dig @127.0.0.1 -p 5349 HS TXT .

...

;; ANSWER SECTION:
hash.tip.chain.hnsd.    0       HS      TXT     "00000000000000060a961fd96887778c460388ff84412d2a74f802a91a13909b"
height.tip.chain.hnsd.  0       HS      TXT     "145806"
time.tip.chain.hnsd.    0       HS      TXT     "1668109101"
synced.chain.hnsd.      0       HS      TXT     "true"
progress.chain.hnsd.    0       HS      TXT     "1.000000"
size.pool.hnsd.         0       HS      TXT     "3"
host.0.peers.pool.hnsd. 0       HS      TXT     "107.152.33.71:44806"
agent.0.peers.pool.hnsd. 0      HS      TXT     "/hsd:3.0.1/"
headers.0.peers.pool.hnsd. 0    HS      TXT     "145806"
proofs.0.peers.pool.hnsd. 0     HS      TXT     "42"
state.0.peers.pool.hnsd. 0      HS      TXT     "HSK_STATE_HANDSHAKE"
host.1.peers.pool.hnsd. 0       HS      TXT     "94.250.201.213:39001"
agent.1.peers.pool.hnsd. 0      HS      TXT     ""
headers.1.peers.pool.hnsd. 0    HS      TXT     "0"
proofs.1.peers.pool.hnsd. 0     HS      TXT     "0"
state.1.peers.pool.hnsd. 0      HS      TXT     "HSK_STATE_CONNECTING"
host.2.peers.pool.hnsd. 0       HS      TXT     "202.61.245.13:39001"
agent.2.peers.pool.hnsd. 0      HS      TXT     ""
headers.2.peers.pool.hnsd. 0    HS      TXT     "0"
proofs.2.peers.pool.hnsd. 0     HS      TXT     "0"
state.2.peers.pool.hnsd. 0      HS      TXT     "HSK_STATE_CONNECTING"

Retrieve the chain sync progress only:

$ dig @127.0.0.1 -p 5349 HS TXT progress.chain.hnsd. +short

"1.000000"

Retrieve data about chain tip block header:

$ dig @127.0.0.1 -p 5349 HS TXT tip.chain.hnsd.

...

;; ANSWER SECTION:
hash.tip.chain.hnsd.    0       HS      TXT     "00000000000000017c9ad1944a32af23819542842c30ebd5c7b99a939c4ba79b"
height.tip.chain.hnsd.  0       HS      TXT     "144656"
time.tip.chain.hnsd.    0       HS      TXT     "1667414685"

@pinheadmz pinheadmz marked this pull request as ready for review November 2, 2022 19:01
src/hesiod.c Outdated
Comment on lines 136 to 144
if (hsk_dns_is_subdomain(req->name, "peers.pool.hnsd.")) {
hsk_peer_t *peerIter, *next;
for (peerIter = ns->pool->head; peerIter; peerIter = next) {
if (!hsk_hesiod_txt_push_peer(peerIter, an))
goto fail;

next = peerIter->next;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

it would be great if instead of peer id, a normal counter is used. Peer ID itself isn't really useful since the ip:port can act as an identifier and a parser's complexity increases when the numbers are non-deterministic.

Technically the parser can get around this by ignoring the number and just pushing onto an array, but imo it's cleaner if the numbers in the names are in order and consecutive.

Otherwise it ends up looking like:

{
  chain: {
    tip: {
      hash: '0000000000000004289e32985c3325ccfcafe6facbbdf3d77908cd2787c6e55c',
      height: '145177',
      time: '1667733359'
    },
    synced: 'true',
    progress: '1.000000'
  },
  pool: { size: '2', peers: [ {}, {}, [Object], [Object] ] }
}

Copy link
Member Author

Choose a reason for hiding this comment

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

added in 6e88475

@rithvikvibhu
Copy link
Member

Other than the peer id comment, everything works great! I liked the wildcard graphql-like selective query part.
Wrote a small client for this API: https://github.com/rithvikvibhu/hnsd-client

Was thinking if we could send more info on peers like state, but the lack of agent for a peer works as an indicator so it's fine ig.

Copy link
Member

@rithvikvibhu rithvikvibhu left a comment

Choose a reason for hiding this comment

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

LFG!! 🚀 🚀

@pinheadmz
Copy link
Member Author

@rithvikvibhu thanks for reviewing and feedback! I'm going to merge as is for now and we can do follow-ups in future PRs.

@pinheadmz pinheadmz merged commit 102210b into handshake-org:master Nov 11, 2022
@pinheadmz
Copy link
Member Author

TODO:

  • link to HS API docs from README

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.

None yet

3 participants