Files
zeekay f728e8fdce The description comes from the binary, not from a file a macro left behind
Writing the manifest fragments during macro expansion had a failure nobody
would see: rustc reuses a cached expansion, so a macro that did not run left
its file saying what the source used to say. A rebuild after deleting one
fragment recompiled the crate and did not restore it — measured — which means a
service could publish a document that quietly disagreed with its own code, the
one failure this whole design exists to prevent.

So the description is compiled IN. `#[derive(zip::Wire)]` gives a type
`stated()`, its manifest entry as a `&'static str`, and `reach()`, which claims
its entry and then asks the types of its fields — the graph is walked by the
types themselves, because a macro sees only the item it is on. `#[zip::ops]`
joins the ops half to whatever the ops reach and hands back `manifest()`. The
service prints it on `--manifest`, so what is projected is what this build
declared and there is nothing to go stale.

That leaves one shape for a manifest instead of two, so zipc reads a document
and no longer merges a directory of fragments; what it refused about a
directory it now refuses about the document, in Manifest.Check beside the
version rule. The example's build script tolerates the documents not existing
yet, which is the state of the one build that makes them.
2026-09-15 11:41:57 -07:00

2 lines
13 KiB
JSON

{"manifest":1,"app":"info","title":"Lux node info","version":"1.0.0","description":"What a Lux node tells anyone who asks: what it is running, what network it is on, who it is connected to, and what its chains cost.","ops":[{"method":"GET","path":"/node/version","description":"NodeVersion is what this node is running: its own release, the database format\nit reads, and the VM protocol it speaks.","pkg":"info","out":"NodeVersion","response":{"version": "luxd/1.36.178", "databaseVersion": "v1.4.5", "rpcProtocolVersion": 39, "gitCommit": ""}},{"method":"GET","path":"/node/id","description":"Identity is this node's id, with the proof it holds the staking key that id is\nderived from.","pkg":"info","out":"NodeID","response":{"nodeID": "NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg", "nodePOP": {"publicKey": "0x8f95", "proofOfPossession": "0x86a3"}}},{"method":"GET","path":"/node/ip","description":"Address is where this node tells its peers to reach it.","pkg":"info","out":"NodeIP","response":{"ip": "203.0.113.9:9651"}},{"method":"GET","path":"/network/id","description":"NetworkID is the number of the network this node is on.","pkg":"info","out":"NetworkID","response":{"networkID": 96369}},{"method":"GET","path":"/network/name","description":"NetworkName is the name of the network this node is on.","pkg":"info","out":"NetworkName","response":{"networkName": "mainnet"}},{"method":"GET","path":"/chain/id","description":"ChainID resolves a chain's alias to the id it names.","pkg":"info","in":"ChainAlias","out":"ChainID","example":{"alias": "X"},"response":{"blockchainID": "2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM"}},{"method":"GET","path":"/chain/bootstrapped","description":"Bootstrapped reports whether a chain has finished bootstrapping on this node.","pkg":"info","in":"BootstrappedArgs","out":"Bootstrapped","example":{"chain": "X"},"response":{"isBootstrapped": true}},{"method":"GET","path":"/chains","description":"Chains are the chains this node is running, which is a subset of the chains\nthe P-Chain knows about.","pkg":"info","out":"Chains","response":{"chains": [{"id": "11111111111111111111111111111111LpoYY", "name": "P-Chain", "vmID": "11111111111111111111111111111111LpoYY", "bootstrapped": true}]}},{"method":"GET","path":"/peers","description":"Peers are the nodes this one is connected to. A list of node ids narrows the\nanswer to those, and no list asks for all of them.","pkg":"info","in":"PeersArgs","out":"Peers","example":{"nodeIDs": []},"response":{"numPeers": "1", "peers": [{"ip": "203.0.113.9:9651", "publicIP": "203.0.113.9:9651", "nodeID": "NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg", "version": "luxd/1.36.178", "observedUptime": 99, "trackedChains": []}]}},{"method":"GET","path":"/lps","description":"LPs is where the network's stake stands on every current Lux Proposal.","pkg":"info","out":"LPs","response":{"lps": {"23": {"supportWeight": "0", "objectWeight": "0", "abstainWeight": "1000000000000"}}}},{"method":"GET","path":"/vms","description":"VMs are the virtual machines installed on this node, and the feature\nextensions its UTXO chains understand.","pkg":"info","out":"VMs","response":{"vms": {"mgj786NP7uDwBCcq6YwThhaN8FLyybkCa4zBWTQbNgmK6k9A6": ["platformvm"]}, "fxs": {"spqBHsy2UBGpjaQJezEywUy1AB98eVjJ3WQ38x1vpjsx4xPkY": "secp256k1fx"}}},{"method":"GET","path":"/upgrades","description":"Upgrades is the upgrade schedule this node runs.","pkg":"info","out":"Upgrades","response":{"stopVertexID": "jrGWDh5Po9FMj54depyunNixpia5PN4aAYxfmNzU8n752Rjga", "epochDuration": "300000000000"}},{"method":"GET","path":"/uptime","description":"Uptime is how much of the network, by stake, reports having seen this node up.","pkg":"info","out":"Uptime","response":{"rewardingStakePercentage": "100.0000", "weightedAveragePercentage": "99.9999"}},{"method":"GET","path":"/fees","description":"Fees are the transaction fees this node charges, in nLUX.","pkg":"info","out":"Fees","response":{"txFee": "1000000", "createAssetTxFee": "10000000", "createChainTxFee": "1000000000"}}],"types":[{"id":"Bootstrapped","name":"Bootstrapped","kind":"struct","spell":"Bootstrapped","doc":"Bootstrapped is whether a chain has finished bootstrapping.","fields":[{"name":"is_bootstrapped","json":"isBootstrapped","doc":"IsBootstrapped is true once the chain has caught up.","type":{"prim":"bool"},"spell":"bool"}]},{"id":"BootstrappedArgs","name":"BootstrappedArgs","kind":"struct","spell":"BootstrappedArgs","doc":"BootstrappedArgs names the chain whose bootstrap state is being asked about.","fields":[{"name":"chain","json":"chain","required":true,"doc":"Chain is the alias or id of the chain to ask about.","type":{"prim":"string"},"spell":"String"}]},{"id":"Chain","name":"Chain","kind":"struct","spell":"Chain","doc":"Chain is one chain this node runs.","fields":[{"name":"id","json":"id","doc":"ID is the chain's id.","type":{"prim":"string"},"spell":"String"},{"name":"name","json":"name","doc":"Name is the chain's name.","type":{"prim":"string"},"spell":"String"},{"name":"vm_id","json":"vmID","doc":"VMID is the id of the virtual machine the chain runs.","type":{"prim":"string"},"spell":"String"},{"name":"bootstrapped","json":"bootstrapped","doc":"Bootstrapped is whether this node has caught the chain up.","type":{"prim":"bool"},"spell":"bool"}]},{"id":"ChainAlias","name":"ChainAlias","kind":"struct","spell":"ChainAlias","doc":"ChainAlias names the chain a caller is asking about.","fields":[{"name":"alias","json":"alias","required":true,"doc":"Alias is the name the chain answers to, such as \"X\".","type":{"prim":"string"},"spell":"String"}]},{"id":"ChainID","name":"ChainID","kind":"struct","spell":"ChainID","doc":"ChainID is the id an alias names.","fields":[{"name":"blockchain_id","json":"blockchainID","doc":"BlockchainID is the chain's id.","type":{"prim":"string"},"spell":"String"}]},{"id":"Chains","name":"Chains","kind":"struct","spell":"Chains","doc":"Chains are the chains this node runs.","fields":[{"name":"chains","json":"chains","doc":"Chains are the chains this node is running.","type":{"list":{"ref":"Chain"}},"spell":"Vec<Chain>"}]},{"id":"Fees","name":"Fees","kind":"struct","spell":"Fees","doc":"Fees are the transaction fees this node charges, in nLUX.","fields":[{"name":"tx_fee","json":"txFee","doc":"TxFee is the fee for an ordinary transaction.","type":{"ref":"Uint64"},"spell":"Uint64"},{"name":"create_asset_tx_fee","json":"createAssetTxFee","doc":"CreateAssetTxFee is the fee to create an asset.","type":{"ref":"Uint64"},"spell":"Uint64"},{"name":"create_chain_tx_fee","json":"createChainTxFee","doc":"CreateChainTxFee is the fee to create a chain.","type":{"ref":"Uint64"},"spell":"Uint64"}]},{"id":"LP","name":"LP","kind":"struct","spell":"LP","doc":"LP is where the stake stands on one proposal.","fields":[{"name":"support_weight","json":"supportWeight","doc":"SupportWeight is the stake in favour.","type":{"ref":"Uint64"},"spell":"Uint64"},{"name":"object_weight","json":"objectWeight","doc":"ObjectWeight is the stake against.","type":{"ref":"Uint64"},"spell":"Uint64"},{"name":"abstain_weight","json":"abstainWeight","doc":"AbstainWeight is the stake that has not said.","type":{"ref":"Uint64"},"spell":"Uint64"}]},{"id":"LPs","name":"LPs","kind":"struct","spell":"LPs","doc":"LPs is where the network's stake stands on every current proposal.","fields":[{"name":"lps","json":"lps","doc":"LPs are the proposals, by number.","type":{"map":{"ref":"LP"}},"spell":"HashMap<String, LP>"}]},{"id":"NetworkID","name":"NetworkID","kind":"struct","spell":"NetworkID","doc":"NetworkID is the number of the network a node is on.","fields":[{"name":"network_id","json":"networkID","doc":"NetworkID is the network's number.","type":{"prim":"u32"},"spell":"u32"}]},{"id":"NetworkName","name":"NetworkName","kind":"struct","spell":"NetworkName","doc":"NetworkName is the name of the network a node is on.","fields":[{"name":"network_name","json":"networkName","doc":"NetworkName is the network's name.","type":{"prim":"string"},"spell":"String"}]},{"id":"NodeID","name":"NodeID","kind":"struct","spell":"NodeID","doc":"NodeID is this node's id, with the proof it holds the staking key.","fields":[{"name":"node_id","json":"nodeID","doc":"NodeID is the id peers know this node by.","type":{"prim":"string"},"spell":"String"},{"name":"node_pop","json":"nodePOP","doc":"NodePOP is the proof this node holds the key its id is derived from.","type":{"ref":"ProofOfPossession"},"spell":"ProofOfPossession"}]},{"id":"NodeIP","name":"NodeIP","kind":"struct","spell":"NodeIP","doc":"NodeIP is where this node tells its peers to reach it.","fields":[{"name":"ip","json":"ip","doc":"IP is the address and port peers dial.","type":{"prim":"string"},"spell":"String"}]},{"id":"NodeVersion","name":"NodeVersion","kind":"struct","spell":"NodeVersion","doc":"NodeVersion is what this node is running.","fields":[{"name":"version","json":"version","doc":"Version is the node's own release.","type":{"prim":"string"},"spell":"String"},{"name":"database_version","json":"databaseVersion","doc":"DatabaseVersion is the database format this node reads.","type":{"prim":"string"},"spell":"String"},{"name":"rpc_protocol_version","json":"rpcProtocolVersion","doc":"RPCProtocolVersion is the VM protocol this node speaks.","type":{"prim":"u32"},"spell":"u32"},{"name":"git_commit","json":"gitCommit","doc":"GitCommit is the commit this node was built from.","type":{"prim":"string"},"spell":"String"}]},{"id":"Peer","name":"Peer","kind":"struct","spell":"Peer","doc":"Peer is one connection this node holds.","fields":[{"name":"ip","json":"ip","doc":"IP is the address this node reaches the peer at.","type":{"prim":"string"},"spell":"String"},{"name":"public_ip","json":"publicIP","doc":"PublicIP is the address the peer tells others to use.","type":{"prim":"string"},"spell":"String"},{"name":"node_id","json":"nodeID","doc":"NodeID is the peer's id.","type":{"prim":"string"},"spell":"String"},{"name":"version","json":"version","doc":"Version is the release the peer is running.","type":{"prim":"string"},"spell":"String"},{"name":"observed_uptime","json":"observedUptime","doc":"ObservedUptime is the share of time this node has seen the peer up.","type":{"prim":"u32"},"spell":"u32"},{"name":"tracked_chains","json":"trackedChains","doc":"TrackedChains are the chains the peer is following.","type":{"list":{"prim":"string"}},"spell":"Vec<String>"}]},{"id":"Peers","name":"Peers","kind":"struct","spell":"Peers","doc":"Peers are the nodes this one is connected to.","fields":[{"name":"num_peers","json":"numPeers","doc":"NumPeers is how many connections this node holds.","type":{"ref":"Uint64"},"spell":"Uint64"},{"name":"peers","json":"peers","doc":"Peers are the connections themselves.","type":{"list":{"ref":"Peer"}},"spell":"Vec<Peer>"}]},{"id":"PeersArgs","name":"PeersArgs","kind":"struct","spell":"PeersArgs","doc":"PeersArgs narrows the peer list to the nodes named.","fields":[{"name":"node_ids","json":"nodeIDs","doc":"NodeIDs are the peers to answer for; none asks for all of them.","type":{"list":{"prim":"string"}},"spell":"Vec<String>"}]},{"id":"ProofOfPossession","name":"ProofOfPossession","kind":"struct","spell":"ProofOfPossession","doc":"ProofOfPossession is a staking key and a signature over it.","fields":[{"name":"public_key","json":"publicKey","doc":"PublicKey is the BLS public key, hex encoded.","type":{"prim":"string"},"spell":"String"},{"name":"proof_of_possession","json":"proofOfPossession","doc":"ProofOfPossession is the signature over that key, hex encoded.","type":{"prim":"string"},"spell":"String"}]},{"id":"Uint64","name":"Uint64","kind":"scalar","spell":"Uint64","repr":"u64","text":true,"json":{"pattern":"^[0-9]+$","type":"string"}},{"id":"Upgrades","name":"Upgrades","kind":"struct","spell":"Upgrades","doc":"Upgrades is the upgrade schedule this node runs.","fields":[{"name":"stop_vertex_id","json":"stopVertexID","doc":"StopVertexID is the vertex the linearisation stopped at.","type":{"prim":"string"},"spell":"String"},{"name":"epoch_duration","json":"epochDuration","doc":"EpochDuration is how long one epoch lasts, in nanoseconds.","type":{"ref":"Uint64"},"spell":"Uint64"}]},{"id":"Uptime","name":"Uptime","kind":"struct","spell":"Uptime","doc":"Uptime is how much of the network reports having seen this node up.","fields":[{"name":"rewarding_stake_percentage","json":"rewardingStakePercentage","doc":"RewardingStakePercentage is the share of stake that would reward this node.","type":{"prim":"string"},"spell":"String"},{"name":"weighted_average_percentage","json":"weightedAveragePercentage","doc":"WeightedAveragePercentage is the stake-weighted average uptime.","type":{"prim":"string"},"spell":"String"}]},{"id":"VMs","name":"VMs","kind":"struct","spell":"VMs","doc":"VMs are the virtual machines installed on this node.","fields":[{"name":"vms","json":"vms","doc":"VMs are the installed machines, by id, each with the names it answers to.","type":{"map":{"list":{"prim":"string"}}},"spell":"HashMap<String, Vec<String>>"},{"name":"fxs","json":"fxs","doc":"Fxs are the feature extensions the UTXO chains understand, by id.","type":{"map":{"prim":"string"}},"spell":"HashMap<String, String>"}]}]}