mirror of
https://github.com/alexgo-io/stacks-subnets.git
synced 2026-01-12 22:43:44 +08:00
add OpenAPI docs for RPC endpoints, update /v2/pox return based on PR feedback
This commit is contained in:
@@ -75,69 +75,7 @@ Reason types without additional information will not have a
|
||||
|
||||
### GET /v2/pox
|
||||
|
||||
Get current PoX-relevant information.
|
||||
|
||||
Returns JSON data in the form:
|
||||
|
||||
```
|
||||
{
|
||||
"contract_id": "SP000000000000000000002Q6VF78.pox",
|
||||
"first_burnchain_block_height": 666050,
|
||||
"next_cycle_cur_threshold": 70000000000,
|
||||
"cur_cycle_threshold": 70000000000,
|
||||
"cur_cycle_stacked_ustx": 202157971547640,
|
||||
"next_cycle_stacked_ustx": 151807880982060,
|
||||
"reward_slots": 4000,
|
||||
"next_rewards_start": 672350,
|
||||
"next_prepare_phase_start": 672250,
|
||||
"min_stacking_increment_ustx": 52251700044,
|
||||
"pox_activation_threshold": 52251700044388,
|
||||
"prepare_cycle_length": 100,
|
||||
"rejection_fraction": 25,
|
||||
"reward_cycle_id": 2,
|
||||
"reward_cycle_length": 2100,
|
||||
"rejection_votes_left_required": 261258500221925,
|
||||
"total_liquid_supply_ustx": 1045034000887772,
|
||||
"next_reward_cycle_in": 1318,
|
||||
"next_prepare_phase_in": 1218
|
||||
}
|
||||
```
|
||||
|
||||
* `contract_id` is the contract identifier for the PoX contract.
|
||||
* `cur_cycle_threshold` is the threshold amount for obtaining a slot in the
|
||||
active reward cycle.
|
||||
* `next_cycle_cur_threshold` is the _current_ microstacks threshold for the
|
||||
_next_ reward cycle. If more STX is locked for participation in that cycle,
|
||||
the threshold may increase.
|
||||
* `first_burnchain_block_height` is the first burn block evaluated in this Stacks
|
||||
chain.
|
||||
* `cur_cycle_stacked_ustx` is the total amount of stacked microstacks in the
|
||||
active reward cycle.
|
||||
* `next_cycle_stacked_ustx` is the total amount of stacked microstacks in the
|
||||
next reward cycle.
|
||||
* `reward_slots` is the number of reward slots in a reward cycle
|
||||
* `next_rewards_start` is the burn block height when the next reward
|
||||
cycle begins
|
||||
* `next_prepare_phase_start` is the burn block height when the next prepare
|
||||
phase begins. Any eligible stacks _must_ be stacked before this block.
|
||||
* `min_stacking_increment_ustx` is the minimum amount that can be used to
|
||||
submit a `stack-stx` call.
|
||||
* `pox_activation_threshold` is the threshold of stacking participation that
|
||||
must be reached for PoX to activate in any cycle.
|
||||
* `prepare_cycle_length` is the length in burn blocks of the prepare phase
|
||||
* `rejection_fraction` is the fraction of liquid STX that must vote to reject
|
||||
PoX in order to prevent the next reward cycle from activating.
|
||||
* `rejection_votes_left_required` is the remaining amount of liquid
|
||||
STX that must vote to reject the next reward cycle to prevent the next
|
||||
reward cycle from activating.
|
||||
* `reward_cycle_id` is the active reward cycle number
|
||||
* `reward_cycle_length` is the length in burn blocks of a whole PoX
|
||||
cycle (reward phase and prepare phase)
|
||||
* `total_liquid_supply_ustx` is the current total amount of liquid microstacks.
|
||||
* `next_reward_cycle_in` is the number of burn blocks until the next reward
|
||||
cycle begins.
|
||||
* `next_prepare_phase_in` is the number of burn blocks until the next prepare
|
||||
phase starts.
|
||||
Get current PoX-relevant information. See OpenAPI [spec](./rpc/openapi.yaml) for details.
|
||||
|
||||
### GET /v2/accounts/[Principal]
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"okay": false,
|
||||
"cause": "Unchecked(PublicFunctionNotReadOnly(..."
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"okay": true,
|
||||
"result": "0x111..."
|
||||
}
|
||||
19
docs/rpc/api/contract/post-call-read-only-fn.schema.json
Normal file
19
docs/rpc/api/contract/post-call-read-only-fn.schema.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "GET request to get contract source",
|
||||
"title": "ReadOnlyFunctionSuccessResponse",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["okay"],
|
||||
"properties": {
|
||||
"okay": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"result": {
|
||||
"type": "string"
|
||||
},
|
||||
"cause": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
8
docs/rpc/api/core-node/get-account-data.example.json
Normal file
8
docs/rpc/api/core-node/get-account-data.example.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"balance": "0x0000000000000000000000000007a120",
|
||||
"locked": "0x0000000000000000000000000007a120",
|
||||
"unlock_height": 126,
|
||||
"nonce": 2867,
|
||||
"balance_proof": "0xabce",
|
||||
"nonce_proof": "0xabcd"
|
||||
}
|
||||
28
docs/rpc/api/core-node/get-account-data.schema.json
Normal file
28
docs/rpc/api/core-node/get-account-data.schema.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "GET request for account data",
|
||||
"title": "AccountDataResponse",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["balance", "locked", "unlock_height", "nonce", "balance_proof", "nonce_proof"],
|
||||
"properties": {
|
||||
"balance": {
|
||||
"type": "string"
|
||||
},
|
||||
"locked": {
|
||||
"type": "string"
|
||||
},
|
||||
"unlock_height": {
|
||||
"type": "integer"
|
||||
},
|
||||
"nonce": {
|
||||
"type": "integer"
|
||||
},
|
||||
"balance_proof": {
|
||||
"type": "string"
|
||||
},
|
||||
"nonce_proof": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"data": "0x0a0c000000010a6d6f6e737465722d69640100000000000000000000000000000001",
|
||||
"proof": "0x123..."
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "Response of get data map entry request",
|
||||
"title": "MapEntryResponse",
|
||||
"type": "object",
|
||||
"required": ["data"],
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "string",
|
||||
"description": "Hex-encoded string of clarity value. It is always an optional tuple."
|
||||
},
|
||||
"proof": {
|
||||
"type": "string",
|
||||
"description": "Hex-encoded string of the MARF proof for the data"
|
||||
}
|
||||
}
|
||||
}
|
||||
134
docs/rpc/api/core-node/get-contract-interface.example.json
Normal file
134
docs/rpc/api/core-node/get-contract-interface.example.json
Normal file
@@ -0,0 +1,134 @@
|
||||
{
|
||||
"functions": [
|
||||
{
|
||||
"name": "get-value",
|
||||
"access": "public",
|
||||
"args": [
|
||||
{
|
||||
"name": "key",
|
||||
"type": {
|
||||
"buffer": {
|
||||
"length": 32
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {
|
||||
"type": {
|
||||
"response": {
|
||||
"ok": {
|
||||
"buffer": {
|
||||
"length": 32
|
||||
}
|
||||
},
|
||||
"error": "int128"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "set-value",
|
||||
"access": "public",
|
||||
"args": [
|
||||
{
|
||||
"name": "key",
|
||||
"type": {
|
||||
"buffer": {
|
||||
"length": 32
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": {
|
||||
"buffer": {
|
||||
"length": 32
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {
|
||||
"type": {
|
||||
"response": {
|
||||
"ok": "uint128",
|
||||
"error": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "test-emit-event",
|
||||
"access": "public",
|
||||
"args": [],
|
||||
"outputs": {
|
||||
"type": {
|
||||
"response": {
|
||||
"ok": "uint128",
|
||||
"error": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "test-event-types",
|
||||
"access": "public",
|
||||
"args": [],
|
||||
"outputs": {
|
||||
"type": {
|
||||
"response": {
|
||||
"ok": "uint128",
|
||||
"error": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"variables": [
|
||||
{
|
||||
"name": "recipient",
|
||||
"type": "principal",
|
||||
"access": "constant"
|
||||
},
|
||||
{
|
||||
"name": "sender",
|
||||
"type": "principal",
|
||||
"access": "constant"
|
||||
}
|
||||
],
|
||||
"maps": [
|
||||
{
|
||||
"name": "store",
|
||||
"key": [
|
||||
{
|
||||
"name": "key",
|
||||
"type": {
|
||||
"buffer": {
|
||||
"length": 32
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"value": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": {
|
||||
"buffer": {
|
||||
"length": 32
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"fungible_tokens": [
|
||||
{
|
||||
"name": "novel-token-19"
|
||||
}
|
||||
],
|
||||
"non_fungible_tokens": [
|
||||
{
|
||||
"name": "hello-nft",
|
||||
"type": "uint128"
|
||||
}
|
||||
]
|
||||
}
|
||||
44
docs/rpc/api/core-node/get-contract-interface.schema.json
Normal file
44
docs/rpc/api/core-node/get-contract-interface.schema.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "GET request to get contract interface",
|
||||
"title": "ContractInterfaceResponse",
|
||||
"type": "object",
|
||||
"required": ["functions", "variables", "maps", "fungible_tokens", "non_fungible_tokens"],
|
||||
"properties": {
|
||||
"functions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object"
|
||||
},
|
||||
"description": "List of defined methods"
|
||||
},
|
||||
"variables": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object"
|
||||
},
|
||||
"description": "List of defined variables"
|
||||
},
|
||||
"maps": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object"
|
||||
},
|
||||
"description": "List of defined data-maps"
|
||||
},
|
||||
"fungible_tokens": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object"
|
||||
},
|
||||
"description": "List of fungible tokens in the contract"
|
||||
},
|
||||
"non_fungible_tokens": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object"
|
||||
},
|
||||
"description": "List of non-fungible tokens in the contract"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
docs/rpc/api/core-node/get-contract-source.example.json
Normal file
5
docs/rpc/api/core-node/get-contract-source.example.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"source": "(define-constant sender 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR)\n(define-constant recipient 'SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G)\n\n(define-fungible-token novel-token-19)\n(begin (ft-mint? novel-token-19 u12 sender))\n(begin (ft-transfer? novel-token-19 u2 sender recipient))\n\n(define-non-fungible-token hello-nft uint)\n(begin (nft-mint? hello-nft u1 sender))\n(begin (nft-mint? hello-nft u2 sender))\n(begin (nft-transfer? hello-nft u1 sender recipient))\n\n(define-public (test-emit-event)\n (begin\n (print \"Event! Hello world\")\n (ok u1)))\n(begin (test-emit-event))\n\n(define-public (test-event-types)\n (begin\n (unwrap-panic (ft-mint? novel-token-19 u3 recipient))\n (unwrap-panic (nft-mint? hello-nft u2 recipient))\n (unwrap-panic (stx-transfer? u60 tx-sender 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR))\n (unwrap-panic (stx-burn? u20 tx-sender))\n (ok u1)))\n\n(define-map store ((key (buff 32))) ((value (buff 32))))\n(define-public (get-value (key (buff 32)))\n (begin\n (match (map-get? store ((key key)))\n entry (ok (get value entry))\n (err 0))))\n(define-public (set-value (key (buff 32)) (value (buff 32)))\n (begin\n (map-set store ((key key)) ((value value)))\n (ok u1)))",
|
||||
"publish_height": 3196,
|
||||
"proof": "0000001104060000001ec4e..."
|
||||
}
|
||||
19
docs/rpc/api/core-node/get-contract-source.schema.json
Normal file
19
docs/rpc/api/core-node/get-contract-source.schema.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "GET request to get contract source",
|
||||
"title": "ContractSourceResponse",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["source", "publish_height", "proof"],
|
||||
"properties": {
|
||||
"source": {
|
||||
"type": "string"
|
||||
},
|
||||
"publish_height": {
|
||||
"type": "integer"
|
||||
},
|
||||
"proof": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
1
docs/rpc/api/core-node/get-fee-transfer.example.json
Normal file
1
docs/rpc/api/core-node/get-fee-transfer.example.json
Normal file
@@ -0,0 +1 @@
|
||||
1
|
||||
7
docs/rpc/api/core-node/get-fee-transfer.schema.json
Normal file
7
docs/rpc/api/core-node/get-fee-transfer.schema.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "GET fee estimates",
|
||||
"title": "CoreNodeFeeResponse",
|
||||
"type": "string",
|
||||
"additionalProperties": false
|
||||
}
|
||||
15
docs/rpc/api/core-node/get-info.example.json
Normal file
15
docs/rpc/api/core-node/get-info.example.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"peer_version": 385875968,
|
||||
"pox_consensus": "17f76e597bab45646956f38dd39573085d72cbc0",
|
||||
"burn_block_height": 16,
|
||||
"stable_pox_consensus": "8e0561978fc5506b68a589c402dad97e862edb59",
|
||||
"stable_burn_block_height": 15,
|
||||
"server_version": "blockstack-core 0.0.1 => 23.0.0.0 (, release build, linux [x86_64])",
|
||||
"network_id": 2147483648,
|
||||
"parent_network_id": 3669344250,
|
||||
"stacks_tip_height": 15,
|
||||
"stacks_tip": "b1807a2d3f7f8c7922f7c1d60d7c34145ade05d789640dc7dc9ec1021e07bb54",
|
||||
"stacks_tip_consensus_hash": "17f76e597bab45646956f38dd39573085d72cbc0",
|
||||
"unanchored_tip": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"exit_at_block_height": null
|
||||
}
|
||||
76
docs/rpc/api/core-node/get-info.schema.json
Normal file
76
docs/rpc/api/core-node/get-info.schema.json
Normal file
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "GET request that core node information",
|
||||
"title": "CoreNodeInfoResponse",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"peer_version",
|
||||
"pox_consensus",
|
||||
"burn_block_height",
|
||||
"stable_pox_consensus",
|
||||
"stable_burn_block_height",
|
||||
"server_version",
|
||||
"network_id",
|
||||
"parent_network_id",
|
||||
"stacks_tip_height",
|
||||
"stacks_tip",
|
||||
"stacks_tip_consensus_hash",
|
||||
"unanchored_tip",
|
||||
"exit_at_block_height"
|
||||
],
|
||||
"properties": {
|
||||
"peer_version": {
|
||||
"type": "integer",
|
||||
"description": "identifies the version number for the networking communication, this should not change while a node is running, and will only change if there's an upgrade"
|
||||
},
|
||||
"pox_consensus": {
|
||||
"type": "string",
|
||||
"description": "is a hash used to identify the burnchain view for a node. it incorporates bitcoin chain information and PoX information. nodes that disagree on this value will appear to each other as forks. this value will change after every block"
|
||||
},
|
||||
"burn_block_height": {
|
||||
"type": "integer",
|
||||
"description": "latest bitcoin chain height"
|
||||
},
|
||||
"stable_pox_consensus": {
|
||||
"type": "string",
|
||||
"description": "same as burn_consensus, but evaluated at stable_burn_block_height"
|
||||
},
|
||||
"stable_burn_block_height": {
|
||||
"type": "integer",
|
||||
"description": "leftover from stacks 1.0, basically always burn_block_height - 1"
|
||||
},
|
||||
"server_version": {
|
||||
"type": "string",
|
||||
"description": "is a version descriptor"
|
||||
},
|
||||
"network_id": {
|
||||
"type": "integer",
|
||||
"description": "is similar to peer_version and will be used to differentiate between different testnets. this value will be different between mainnet and testnet. once launched, this value will not change"
|
||||
},
|
||||
"parent_network_id": {
|
||||
"type": "integer",
|
||||
"description": "same as network_id, but for bitcoin"
|
||||
},
|
||||
"stacks_tip_height": {
|
||||
"type": "integer",
|
||||
"description": "the latest Stacks chain height. Stacks forks can occur independent of the Bitcoin chain, that height doesn't increase 1-to-1 with the Bitcoin height"
|
||||
},
|
||||
"stacks_tip": {
|
||||
"type": "string",
|
||||
"description": "the best known block hash for the Stack chain (not including any pending microblocks)"
|
||||
},
|
||||
"stacks_tip_consensus_hash": {
|
||||
"type": "string",
|
||||
"description": "the burn chain (i.e., bitcoin) consensus hash at the time that stacks_tip was mined"
|
||||
},
|
||||
"unanchored_tip": {
|
||||
"type": "string",
|
||||
"description": "the latest microblock hash if any microblocks were processed. if no microblock has been processed for the current block, a 000.., hex array is returned"
|
||||
},
|
||||
"exit_at_block_height": {
|
||||
"type": "integer",
|
||||
"description": "the block height at which the testnet network will be reset. not applicable for mainnet"
|
||||
}
|
||||
}
|
||||
}
|
||||
33
docs/rpc/api/core-node/get-pox.example.json
Normal file
33
docs/rpc/api/core-node/get-pox.example.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"contract_id": "SP000000000000000000002Q6VF78.pox",
|
||||
"pox_activation_threshold_ustx": 52329761604388,
|
||||
"first_burnchain_block_height": 666050,
|
||||
"prepare_phase_block_length": 100,
|
||||
"reward_phase_block_length": 2000,
|
||||
"reward_slots": 4000,
|
||||
"rejection_fraction": 25,
|
||||
"total_liquid_supply_ustx": 1046595232087772,
|
||||
"current_cycle": {
|
||||
"id": 2,
|
||||
"min_threshold_ustx": 70000000000,
|
||||
"stacked_ustx": 202157971547640,
|
||||
"is_pox_active": true
|
||||
},
|
||||
"next_cycle": {
|
||||
"id": 3,
|
||||
"min_threshold_ustx": 70000000000,
|
||||
"min_increment_ustx": 52329761604,
|
||||
"stacked_ustx": 162057034977640,
|
||||
"prepare_phase_start_block_height": 672250,
|
||||
"blocks_until_prepare_phase": 407,
|
||||
"reward_phase_start_block_height": 672350,
|
||||
"blocks_until_reward_phase": 507,
|
||||
"ustx_until_pox_rejection": 261648808021925
|
||||
},
|
||||
"min_amount_ustx": 70000000000,
|
||||
"prepare_cycle_length": 100,
|
||||
"reward_cycle_id": 2,
|
||||
"reward_cycle_length": 2100,
|
||||
"rejection_votes_left_required": 261648808021925,
|
||||
"next_reward_cycle_in": 507
|
||||
}
|
||||
160
docs/rpc/api/core-node/get-pox.schema.json
Normal file
160
docs/rpc/api/core-node/get-pox.schema.json
Normal file
@@ -0,0 +1,160 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "Get Proof of Transfer (PoX) information",
|
||||
"title": "CoreNodePoxResponse",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"contract_id",
|
||||
"first_burnchain_block_height",
|
||||
"pox_activation_threshold_ustx",
|
||||
"prepare_phase_block_length",
|
||||
"reward_phase_block_length",
|
||||
"reward_slots",
|
||||
"rejection_fraction",
|
||||
"total_liquid_supply_ustx",
|
||||
"current_cycle",
|
||||
"next_cycle",
|
||||
"reward_cycle_length",
|
||||
"min_amount_ustx",
|
||||
"reward_cycle_id",
|
||||
"prepare_cycle_length",
|
||||
"rejection_votes_left_required"
|
||||
],
|
||||
"properties": {
|
||||
"contract_id": {
|
||||
"type": "string",
|
||||
"description": "The contract identifier for the PoX contract"
|
||||
},
|
||||
"first_burnchain_block_height": {
|
||||
"type": "integer",
|
||||
"description": "The first burn block evaluated in this Stacks chain"
|
||||
},
|
||||
"pox_activation_threshold_ustx": {
|
||||
"type": "integer",
|
||||
"description": "The threshold of stacking participation that must be reached for PoX to activate in any cycle"
|
||||
},
|
||||
"rejection_fraction": {
|
||||
"type": "integer",
|
||||
"description": "The fraction of liquid STX that must vote to reject PoX in order to prevent the next reward cycle from activating."
|
||||
},
|
||||
"reward_phase_block_length": {
|
||||
"type": "integer",
|
||||
"description": "The length in burn blocks of the reward phase"
|
||||
},
|
||||
"prepare_phase_block_length": {
|
||||
"type": "integer",
|
||||
"description": "The length in burn blocks of the prepare phase"
|
||||
},
|
||||
"reward_slots": {
|
||||
"type": "integer",
|
||||
"description": "The number of reward slots in a reward cycle"
|
||||
},
|
||||
"total_liquid_supply_ustx": {
|
||||
"type": "integer",
|
||||
"description": "The current total amount of liquid microstacks."
|
||||
},
|
||||
"reward_cycle_length": {
|
||||
"type": "integer",
|
||||
"description": "The length in burn blocks of a whole PoX cycle (reward phase and prepare phase)"
|
||||
},
|
||||
"current_cycle": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"id",
|
||||
"min_threshold_ustx",
|
||||
"stacked_ustx",
|
||||
"is_pox_active"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"description": "The reward cycle number"
|
||||
},
|
||||
"min_threshold_ustx": {
|
||||
"type": "integer",
|
||||
"description": "The threshold amount for obtaining a slot in this reward cycle."
|
||||
},
|
||||
"stacked_ustx": {
|
||||
"type": "integer",
|
||||
"description": "The total amount of stacked microstacks in this reward cycle."
|
||||
},
|
||||
"is_pox_active": {
|
||||
"type": "boolean",
|
||||
"description": "Whether or not PoX is active during this reward cycle."
|
||||
},
|
||||
}
|
||||
},
|
||||
"next_cycle": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"id",
|
||||
"min_threshold_ustx",
|
||||
"stacked_ustx",
|
||||
"min_increment_ustx",
|
||||
"prepare_phase_start_block_height",
|
||||
"blocks_until_prepare_phase",
|
||||
"reward_phase_start_block_height",
|
||||
"blocks_until_reward_phase",
|
||||
"ustx_until_pox_rejection"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"description": "The reward cycle number"
|
||||
},
|
||||
"min_threshold_ustx": {
|
||||
"type": "integer",
|
||||
"description": "The threshold amount for obtaining a slot in this reward cycle."
|
||||
},
|
||||
"stacked_ustx": {
|
||||
"type": "integer",
|
||||
"description": "The total amount of stacked microstacks in this reward cycle."
|
||||
},
|
||||
"min_increment_ustx": {
|
||||
"type": "integer",
|
||||
"description": "The minimum amount that can be used to submit a `stack-stx` call."
|
||||
},
|
||||
"prepare_phase_start_block_height": {
|
||||
"type": "integer",
|
||||
"description": "The burn block height when the prepare phase for this cycle begins. Any eligible stacks must be stacked before this block."
|
||||
},
|
||||
"blocks_until_prepare_phase": {
|
||||
"type": "integer",
|
||||
"description": "The number of burn blocks until the prepare phase for this cycle starts. If the prepare phase for this cycle already started, this value will be negative."
|
||||
},
|
||||
"reward_phase_start_block_height": {
|
||||
"type": "integer",
|
||||
"description": "The burn block height when the reward phase for this cycle begins. Any eligible stacks must be stacked before this block."
|
||||
},
|
||||
"blocks_until_reward_phase": {
|
||||
"type": "integer",
|
||||
"description": "The number of burn blocks until this reward phase starts."
|
||||
},
|
||||
"ustx_until_pox_rejection": {
|
||||
"type": "integer",
|
||||
"description": "The remaining amount of liquid STX that must vote to reject the next reward cycle to prevent the next reward cycle from activating."
|
||||
}
|
||||
}
|
||||
},
|
||||
"reward_cycle_id": {
|
||||
"type": "integer",
|
||||
"deprecated": true,
|
||||
"description": "The active reward cycle number"
|
||||
},
|
||||
"min_amount_ustx": {
|
||||
"type": "integer",
|
||||
"deprecated": true,
|
||||
},
|
||||
"prepare_cycle_length": {
|
||||
"type": "integer",
|
||||
"deprecated": true,
|
||||
},
|
||||
"rejection_votes_left_required": {
|
||||
"type": "integer",
|
||||
"deprecated": true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"error": "transaction rejected",
|
||||
"reason": "BadNonce",
|
||||
"reason_data": {
|
||||
"actual": 4,
|
||||
"expected": 0,
|
||||
"is_origin": true,
|
||||
"principal": "ST2ZRX0K27GW0SP3GJCEMHD95TQGJMKB7G9Y0X1MH"
|
||||
},
|
||||
"txid": "caf6fd60ae05b0c2d19ef14ab6a7670b1095d117fa7c80224c74e76214d0a791"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "GET request that returns transactions",
|
||||
"title": "PostCoreNodeTransactionsError",
|
||||
"type": "object",
|
||||
"required": ["error", "reason", "reason_data", "txid"],
|
||||
"properties": {
|
||||
"error": {
|
||||
"type": "string",
|
||||
"description": "The error"
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"description": "The reason for the error"
|
||||
},
|
||||
"reason_data": {
|
||||
"type": "object",
|
||||
"description": "More details about the reason"
|
||||
},
|
||||
"txid": {
|
||||
"type": "string",
|
||||
"description": "The relevant transaction id"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "ReadOnlyFunctionArgs",
|
||||
"description": "Describes representation of a Type-0 Stacks 2.0 transaction. https://github.com/blockstack/stacks-blockchain/blob/master/sip/sip-005-blocks-and-transactions.md#type-0-transferring-an-asset",
|
||||
"type": "object",
|
||||
"required": ["sender", "arguments"],
|
||||
"properties": {
|
||||
"sender": {
|
||||
"type": "string",
|
||||
"description": "The simulated tx-sender"
|
||||
},
|
||||
"arguments": {
|
||||
"type": "array",
|
||||
"description": "An array of hex serialized Clarity values",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
328
docs/rpc/openapi.yaml
Normal file
328
docs/rpc/openapi.yaml
Normal file
@@ -0,0 +1,328 @@
|
||||
openapi: 3.0.2
|
||||
servers:
|
||||
- url: http://localhost:20443/
|
||||
description: Local
|
||||
info:
|
||||
title: Stacks 2.0 RPC API
|
||||
version: '1.0.0'
|
||||
description: |
|
||||
This is the documentation for the `stacks-node` RPC interface.
|
||||
|
||||
paths:
|
||||
/v2/transactions:
|
||||
post:
|
||||
summary: Broadcast raw transaction
|
||||
tags:
|
||||
- Transactions
|
||||
description: Broadcast raw transactions on the network. You can use the [@stacks/transactions](https://github.com/blockstack/stacks.js) project to generate a raw transaction payload.
|
||||
operationId: post_core_node_transactions
|
||||
requestBody:
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
example: binary format of 00000000010400bed38c2aadffa348931bcb542880ff79d607afec000000000000000000000000000000c800012b0b1fff6cccd0974966dcd665835838f0985be508e1322e09fb3d751eca132c492bda720f9ef1768d14fdabed6127560ba52d5e3ac470dcb60b784e97dc88c9030200000000000516df0ba3e79792be7be5e50a370289accfc8c9e032000000000000303974657374206d656d6f00000000000000000000000000000000000000000000000000
|
||||
responses:
|
||||
200:
|
||||
description: Transaction id of successful post of a raw tx to the node's mempool
|
||||
content:
|
||||
text/plain:
|
||||
schema:
|
||||
type: string
|
||||
example: '"e161978626f216b2141b156ade10501207ae535fa365a13ef5d7a7c9310a09f2"'
|
||||
400:
|
||||
description: Rejections result in a 400 error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: ./api/transaction/post-core-node-transactions-error.schema.json
|
||||
example:
|
||||
$ref: ./api/transaction/post-core-node-transactions-error.example.json
|
||||
|
||||
/v2/contracts/interface/{contract_address}/{contract_name}:
|
||||
get:
|
||||
summary: Get contract interface
|
||||
description: Get contract interface using a `contract_address` and `contract name`
|
||||
tags:
|
||||
- Smart Contracts
|
||||
operationId: get_contract_interface
|
||||
responses:
|
||||
200:
|
||||
description: Contract interface
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: ./api/core-node/get-contract-interface.schema.json
|
||||
example:
|
||||
$ref: ./api/core-node/get-contract-interface.example.json
|
||||
parameters:
|
||||
- name: contract_address
|
||||
in: path
|
||||
required: true
|
||||
description: Stacks address
|
||||
schema:
|
||||
type: string
|
||||
- name: contract_name
|
||||
in: path
|
||||
required: true
|
||||
description: Contract name
|
||||
schema:
|
||||
type: string
|
||||
- name: tip
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: The Stacks chain tip to query from
|
||||
|
||||
/v2/map_entry/{contract_address}/{contract_name}/{map_name}:
|
||||
post:
|
||||
summary: Get specific data-map inside a contract
|
||||
tags:
|
||||
- Smart Contracts
|
||||
operationId: get_contract_data_map_entry
|
||||
description: |
|
||||
Attempt to fetch data from a contract data map. The contract is identified with [Stacks Address] and [Contract Name] in the URL path. The map is identified with [Map Name].
|
||||
|
||||
The key to lookup in the map is supplied via the POST body. This should be supplied as the hex string serialization of the key (which should be a Clarity value). Note, this is a JSON string atom.
|
||||
|
||||
In the response, `data` is the hex serialization of the map response. Note that map responses are Clarity option types, for non-existent values, this is a serialized none, and for all other responses, it is a serialized (some ...) object.
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: ./api/core-node/get-contract-data-map-entry.schema.json
|
||||
example:
|
||||
$ref: ./api/core-node/get-contract-data-map-entry.example.json
|
||||
400:
|
||||
description: Failed loading data map
|
||||
parameters:
|
||||
- name: contract_address
|
||||
in: path
|
||||
required: true
|
||||
description: Stacks address
|
||||
schema:
|
||||
type: string
|
||||
- name: contract_name
|
||||
in: path
|
||||
required: true
|
||||
description: Contract name
|
||||
schema:
|
||||
type: string
|
||||
- name: map_name
|
||||
in: path
|
||||
required: true
|
||||
description: Map name
|
||||
schema:
|
||||
type: string
|
||||
- name: proof
|
||||
in: query
|
||||
description: Returns object without the proof field when set to 0
|
||||
schema:
|
||||
type: integer
|
||||
- name: tip
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: The Stacks chain tip to query from
|
||||
x-codegen-request-body-name: key
|
||||
requestBody:
|
||||
description: Hex string serialization of the lookup key (which should be a Clarity value)
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: string
|
||||
|
||||
/v2/contracts/source/{contract_address}/{contract_name}:
|
||||
get:
|
||||
summary: Get contract source
|
||||
tags:
|
||||
- Smart Contracts
|
||||
operationId: get_contract_source
|
||||
description: Returns the Clarity source code of a given contract, along with the block height it was published in, and the MARF proof for the data
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: ./api/core-node/get-contract-source.schema.json
|
||||
example:
|
||||
$ref: ./api/core-node/get-contract-source.example.json
|
||||
parameters:
|
||||
- name: contract_address
|
||||
in: path
|
||||
required: true
|
||||
description: Stacks address
|
||||
schema:
|
||||
type: string
|
||||
- name: contract_name
|
||||
in: path
|
||||
required: true
|
||||
description: Contract name
|
||||
schema:
|
||||
type: string
|
||||
- name: proof
|
||||
in: query
|
||||
description: Returns object without the proof field if set to 0
|
||||
schema:
|
||||
type: integer
|
||||
- name: tip
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: The Stacks chain tip to query from
|
||||
required: false
|
||||
|
||||
/v2/contracts/call-read/{contract_address}/{contract_name}/{function_name}:
|
||||
post:
|
||||
summary: Call read-only function
|
||||
tags:
|
||||
- Smart Contracts
|
||||
operationId: call_read_only_function
|
||||
description: |
|
||||
Call a read-only public function on a given smart contract.
|
||||
|
||||
The smart contract and function are specified using the URL path. The arguments and the simulated tx-sender are supplied via the POST body in the following JSON format:
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: ./api/contract/post-call-read-only-fn.schema.json
|
||||
examples:
|
||||
success:
|
||||
$ref: ./api/contract/post-call-read-only-fn-success.example.json
|
||||
fail:
|
||||
$ref: ./api/contract/post-call-read-only-fn-fail.example.json
|
||||
parameters:
|
||||
- name: contract_address
|
||||
in: path
|
||||
required: true
|
||||
description: Stacks address
|
||||
schema:
|
||||
type: string
|
||||
- name: contract_name
|
||||
in: path
|
||||
required: true
|
||||
description: Contract name
|
||||
schema:
|
||||
type: string
|
||||
- name: function_name
|
||||
in: path
|
||||
required: true
|
||||
description: Function name
|
||||
schema:
|
||||
type: string
|
||||
- name: tip
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: The Stacks chain tip to query from
|
||||
required: false
|
||||
requestBody:
|
||||
description: map of arguments and the simulated tx-sender where sender is either a Contract identifier or a normal Stacks address, and arguments is an array of hex serialized Clarity values.
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: './entities/contracts/read-only-function-args.schema.json'
|
||||
example:
|
||||
sender: 'SP31DA6FTSJX2WGTZ69SFY11BH51NZMB0ZW97B5P0.get-info'
|
||||
arguments:
|
||||
- '0x0011...'
|
||||
- '0x00231...'
|
||||
|
||||
/v2/accounts/{principal}:
|
||||
get:
|
||||
summary: Get account info
|
||||
tags:
|
||||
- Accounts
|
||||
operationId: get_account_info
|
||||
description: |
|
||||
Get the account data for the provided principal
|
||||
|
||||
Where balance is the hex encoding of a unsigned 128-bit integer (big-endian), nonce is a unsigned 64-bit integer, and the proofs are provided as hex strings.
|
||||
|
||||
For non-existent accounts, this does not 404, rather it returns an object with balance and nonce of 0.
|
||||
parameters:
|
||||
- name: principal
|
||||
in: path
|
||||
description: Stacks address or a Contract identifier (e.g. `SP31DA6FTSJX2WGTZ69SFY11BH51NZMB0ZW97B5P0.get-info`)
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: proof
|
||||
in: query
|
||||
description: Returns object without the proof field if set to 0
|
||||
schema:
|
||||
type: integer
|
||||
- name: tip
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
description: The Stacks chain tip to query from
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: ./api/core-node/get-account-data.schema.json
|
||||
example:
|
||||
$ref: ./api/core-node/get-account-data.example.json
|
||||
|
||||
/v2/fees/transfer:
|
||||
get:
|
||||
summary: Get estimated fee
|
||||
tags:
|
||||
- Fees
|
||||
operationId: get_fee_transfer
|
||||
description: Get an estimated fee rate for STX transfer transactions. This a a fee rate / byte, and is returned as a JSON integer
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: ./api/core-node/get-fee-transfer.schema.json
|
||||
example:
|
||||
$ref: ./api/core-node/get-fee-transfer.example.json
|
||||
|
||||
/v2/info:
|
||||
get:
|
||||
summary: Get Core API info
|
||||
description: Get Core API information
|
||||
tags:
|
||||
- Info
|
||||
operationId: get_core_api_info
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: ./api/core-node/get-info.schema.json
|
||||
example:
|
||||
$ref: ./api/core-node/get-info.example.json
|
||||
|
||||
/v2/pox:
|
||||
get:
|
||||
summary: Get PoX details
|
||||
description: Get Proof of Transfer (PoX) information. Can be used for Stacking.
|
||||
tags:
|
||||
- Info
|
||||
operationId: get_pox_info
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: ./api/core-node/get-pox.schema.json
|
||||
example:
|
||||
$ref: ./api/core-node/get-pox.example.json
|
||||
@@ -1455,6 +1455,15 @@ impl<'a> SortitionHandleConn<'a> {
|
||||
Ok(anchor_block_hash)
|
||||
}
|
||||
|
||||
fn get_reward_set_size(&self) -> Result<u16, db_error> {
|
||||
self.get_tip_indexed(&db_keys::pox_reward_set_size())
|
||||
.map(|x| {
|
||||
db_keys::reward_set_size_from_string(
|
||||
&x.expect("CORRUPTION: no current reward set size written"),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_pox_id(&self) -> Result<PoxId, db_error> {
|
||||
let pox_id = self
|
||||
.get_tip_indexed(db_keys::pox_identifier())?
|
||||
@@ -2938,6 +2947,24 @@ impl SortitionDB {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_pox_active(
|
||||
&self,
|
||||
burnchain: &Burnchain,
|
||||
block: &BlockSnapshot,
|
||||
) -> Result<bool, db_error> {
|
||||
let reward_start_height = burnchain.reward_cycle_to_block_height(
|
||||
burnchain
|
||||
.block_height_to_reward_cycle(block.block_height)
|
||||
.ok_or_else(|| db_error::NotFoundError)?,
|
||||
);
|
||||
let sort_id_of_start =
|
||||
get_ancestor_sort_id(&self.index_conn(), reward_start_height, &block.sortition_id)?
|
||||
.ok_or_else(|| db_error::NotFoundError)?;
|
||||
|
||||
let handle = self.index_handle(&sort_id_of_start);
|
||||
Ok(handle.get_reward_set_size()? > 0)
|
||||
}
|
||||
|
||||
/// Find out how any burn tokens were destroyed in a given block on a given fork.
|
||||
pub fn get_block_burn_amount(
|
||||
conn: &Connection,
|
||||
|
||||
@@ -1022,28 +1022,48 @@ pub struct RPCPeerInfoData {
|
||||
pub exit_at_block_height: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct RPCPoxCurrentCycleInfo {
|
||||
pub id: u64,
|
||||
pub min_threshold_ustx: u64,
|
||||
pub stacked_ustx: u64,
|
||||
pub is_pox_active: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct RPCPoxNextCycleInfo {
|
||||
pub id: u64,
|
||||
pub min_threshold_ustx: u64,
|
||||
pub min_increment_ustx: u64,
|
||||
pub stacked_ustx: u64,
|
||||
pub prepare_phase_start_block_height: u64,
|
||||
pub blocks_until_prepare_phase: i64,
|
||||
pub reward_phase_start_block_height: u64,
|
||||
pub blocks_until_reward_phase: u64,
|
||||
pub ustx_until_pox_rejection: u64,
|
||||
}
|
||||
|
||||
/// The data we return on GET /v2/pox
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct RPCPoxInfoData {
|
||||
pub contract_id: String,
|
||||
pub pox_activation_threshold_ustx: u64,
|
||||
pub first_burnchain_block_height: u64,
|
||||
pub next_cycle_cur_threshold: u64,
|
||||
pub cur_cycle_threshold: u64,
|
||||
pub cur_cycle_stacked_ustx: u64,
|
||||
pub next_cycle_stacked_ustx: u64,
|
||||
pub prepare_phase_block_length: u64,
|
||||
pub reward_phase_block_length: u64,
|
||||
pub reward_slots: u64,
|
||||
pub next_rewards_start: u64,
|
||||
pub next_prepare_phase_start: u64,
|
||||
pub min_stacking_increment_ustx: u64,
|
||||
pub pox_activation_threshold: u64,
|
||||
pub prepare_cycle_length: u64,
|
||||
pub rejection_fraction: u64,
|
||||
pub total_liquid_supply_ustx: u64,
|
||||
pub current_cycle: RPCPoxCurrentCycleInfo,
|
||||
pub next_cycle: RPCPoxNextCycleInfo,
|
||||
|
||||
// below are included for backwards-compatibility
|
||||
pub min_amount_ustx: u64,
|
||||
pub prepare_cycle_length: u64,
|
||||
pub reward_cycle_id: u64,
|
||||
pub reward_cycle_length: u64,
|
||||
pub rejection_votes_left_required: u64,
|
||||
pub total_liquid_supply_ustx: u64,
|
||||
pub next_reward_cycle_in: u64,
|
||||
pub next_prepare_phase_in: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Copy, Hash)]
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
along with Blockstack. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use std::net::SocketAddr;
|
||||
use std::{convert::TryFrom, fmt};
|
||||
|
||||
use core::mempool::*;
|
||||
use net::atlas::{AtlasDB, Attachment, MAX_ATTACHMENT_INV_PAGES_PER_REQUEST};
|
||||
@@ -108,6 +108,8 @@ use vm::{
|
||||
use rand::prelude::*;
|
||||
use rand::thread_rng;
|
||||
|
||||
use super::{RPCPoxCurrentCycleInfo, RPCPoxNextCycleInfo};
|
||||
|
||||
pub const STREAM_CHUNK_SIZE: u64 = 4096;
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -338,18 +340,13 @@ impl RPCPoxInfoData {
|
||||
let next_reward_cycle_in = reward_cycle_length - (effective_height % reward_cycle_length);
|
||||
|
||||
let next_rewards_start = burnchain_tip.block_height + next_reward_cycle_in;
|
||||
let next_reward_cycle_prepare_phase_start = next_rewards_start - prepare_cycle_length;
|
||||
let next_prepare_phase_start = next_rewards_start - prepare_cycle_length;
|
||||
|
||||
let next_prepare_phase_start =
|
||||
if burnchain_tip.block_height < next_reward_cycle_prepare_phase_start {
|
||||
next_reward_cycle_prepare_phase_start
|
||||
} else {
|
||||
// currently in a prepare phase, so the next prepare phase start is actually the reward cycle after
|
||||
// next
|
||||
next_reward_cycle_prepare_phase_start + reward_cycle_length
|
||||
};
|
||||
|
||||
let next_prepare_phase_in = next_prepare_phase_start - burnchain_tip.block_height;
|
||||
let next_prepare_phase_in = i64::try_from(next_prepare_phase_start)
|
||||
.map_err(|_| net_error::ChainstateError("Burn block height overflowed i64".into()))?
|
||||
- i64::try_from(burnchain_tip.block_height).map_err(|_| {
|
||||
net_error::ChainstateError("Burn block height overflowed i64".into())
|
||||
})?;
|
||||
|
||||
let cur_cycle_stacked_ustx =
|
||||
chainstate.get_total_ustx_stacked(&sortdb, tip, reward_cycle_id as u128)?;
|
||||
@@ -370,31 +367,45 @@ impl RPCPoxInfoData {
|
||||
reward_slots as u128,
|
||||
) as u64;
|
||||
|
||||
let pox_activation_threshold = (total_liquid_supply_ustx as u128)
|
||||
let pox_activation_threshold_ustx = (total_liquid_supply_ustx as u128)
|
||||
.checked_mul(pox_consts.pox_participation_threshold_pct as u128)
|
||||
.map(|x| x / 100)
|
||||
.ok_or_else(|| net_error::DBError(db_error::Overflow))?
|
||||
as u64;
|
||||
|
||||
let cur_cycle_pox_active = sortdb.is_pox_active(burnchain, &burnchain_tip)?;
|
||||
|
||||
Ok(RPCPoxInfoData {
|
||||
contract_id: boot::boot_code_id("pox", chainstate.mainnet).to_string(),
|
||||
pox_activation_threshold_ustx,
|
||||
first_burnchain_block_height,
|
||||
min_stacking_increment_ustx,
|
||||
next_cycle_cur_threshold: next_threshold,
|
||||
cur_cycle_threshold,
|
||||
next_cycle_stacked_ustx: next_cycle_stacked_ustx as u64,
|
||||
cur_cycle_stacked_ustx: cur_cycle_stacked_ustx as u64,
|
||||
prepare_phase_block_length: prepare_cycle_length,
|
||||
reward_phase_block_length: reward_cycle_length - prepare_cycle_length,
|
||||
reward_slots,
|
||||
pox_activation_threshold,
|
||||
next_rewards_start,
|
||||
next_prepare_phase_start,
|
||||
next_prepare_phase_in,
|
||||
prepare_cycle_length,
|
||||
rejection_fraction,
|
||||
total_liquid_supply_ustx,
|
||||
current_cycle: RPCPoxCurrentCycleInfo {
|
||||
id: reward_cycle_id,
|
||||
min_threshold_ustx: cur_cycle_threshold,
|
||||
stacked_ustx: cur_cycle_stacked_ustx as u64,
|
||||
is_pox_active: cur_cycle_pox_active,
|
||||
},
|
||||
next_cycle: RPCPoxNextCycleInfo {
|
||||
id: reward_cycle_id + 1,
|
||||
min_threshold_ustx: next_threshold,
|
||||
min_increment_ustx: min_stacking_increment_ustx,
|
||||
stacked_ustx: next_cycle_stacked_ustx as u64,
|
||||
prepare_phase_start_block_height: next_prepare_phase_start,
|
||||
blocks_until_prepare_phase: next_prepare_phase_in,
|
||||
reward_phase_start_block_height: next_rewards_start,
|
||||
blocks_until_reward_phase: next_reward_cycle_in,
|
||||
ustx_until_pox_rejection: rejection_votes_left_required,
|
||||
},
|
||||
min_amount_ustx: next_threshold,
|
||||
prepare_cycle_length,
|
||||
reward_cycle_id,
|
||||
reward_cycle_length,
|
||||
rejection_votes_left_required,
|
||||
total_liquid_supply_ustx,
|
||||
next_reward_cycle_in,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2090,14 +2090,15 @@ fn pox_integration_test() {
|
||||
&format!("ST000000000000000000002AMW42H.pox")
|
||||
);
|
||||
assert_eq!(pox_info.first_burnchain_block_height, 0);
|
||||
assert_eq!(pox_info.next_cycle_cur_threshold, 125080000000000);
|
||||
assert_eq!(pox_info.cur_cycle_threshold, 125080000000000);
|
||||
assert_eq!(pox_info.cur_cycle_stacked_ustx, 0);
|
||||
assert_eq!(pox_info.next_cycle_stacked_ustx, 0);
|
||||
assert_eq!(pox_info.next_cycle.min_threshold_ustx, 125080000000000);
|
||||
assert_eq!(pox_info.current_cycle.min_threshold_ustx, 125080000000000);
|
||||
assert_eq!(pox_info.current_cycle.stacked_ustx, 0);
|
||||
assert_eq!(pox_info.current_cycle.is_pox_active, false);
|
||||
assert_eq!(pox_info.next_cycle.stacked_ustx, 0);
|
||||
assert_eq!(pox_info.reward_slots as u32, pox_constants.reward_slots());
|
||||
assert_eq!(pox_info.next_rewards_start, 210);
|
||||
assert_eq!(pox_info.next_prepare_phase_start, 205);
|
||||
assert_eq!(pox_info.min_stacking_increment_ustx, 20845173515333);
|
||||
assert_eq!(pox_info.next_cycle.reward_phase_start_block_height, 210);
|
||||
assert_eq!(pox_info.next_cycle.prepare_phase_start_block_height, 205);
|
||||
assert_eq!(pox_info.next_cycle.min_increment_ustx, 20845173515333);
|
||||
assert_eq!(
|
||||
pox_info.prepare_cycle_length as u32,
|
||||
pox_constants.prepare_length
|
||||
@@ -2107,6 +2108,8 @@ fn pox_integration_test() {
|
||||
pox_constants.pox_rejection_fraction
|
||||
);
|
||||
assert_eq!(pox_info.reward_cycle_id, 0);
|
||||
assert_eq!(pox_info.current_cycle.id, 0);
|
||||
assert_eq!(pox_info.next_cycle.id, 1);
|
||||
assert_eq!(
|
||||
pox_info.reward_cycle_length as u32,
|
||||
pox_constants.reward_cycle_length
|
||||
@@ -2155,13 +2158,15 @@ fn pox_integration_test() {
|
||||
&format!("ST000000000000000000002AMW42H.pox")
|
||||
);
|
||||
assert_eq!(pox_info.first_burnchain_block_height, 0);
|
||||
assert_eq!(pox_info.next_cycle_cur_threshold, 125080000000000);
|
||||
assert_eq!(pox_info.cur_cycle_threshold, 125080000000000);
|
||||
assert_eq!(pox_info.cur_cycle_stacked_ustx, 1000000000000000);
|
||||
assert_eq!(pox_info.next_cycle_stacked_ustx, 1000000000000000);
|
||||
assert_eq!(pox_info.next_cycle.min_threshold_ustx, 125080000000000);
|
||||
assert_eq!(pox_info.current_cycle.min_threshold_ustx, 125080000000000);
|
||||
assert_eq!(pox_info.current_cycle.stacked_ustx, 1000000000000000);
|
||||
assert!(pox_info.pox_activation_threshold_ustx > 1500000000000000);
|
||||
assert_eq!(pox_info.current_cycle.is_pox_active, false);
|
||||
assert_eq!(pox_info.next_cycle.stacked_ustx, 1000000000000000);
|
||||
assert_eq!(pox_info.reward_slots as u32, pox_constants.reward_slots());
|
||||
assert_eq!(pox_info.next_rewards_start, 225);
|
||||
assert_eq!(pox_info.next_prepare_phase_start, 220);
|
||||
assert_eq!(pox_info.next_cycle.reward_phase_start_block_height, 225);
|
||||
assert_eq!(pox_info.next_cycle.prepare_phase_start_block_height, 220);
|
||||
assert_eq!(
|
||||
pox_info.prepare_cycle_length as u32,
|
||||
pox_constants.prepare_length
|
||||
@@ -2171,6 +2176,8 @@ fn pox_integration_test() {
|
||||
pox_constants.pox_rejection_fraction
|
||||
);
|
||||
assert_eq!(pox_info.reward_cycle_id, 14);
|
||||
assert_eq!(pox_info.current_cycle.id, 14);
|
||||
assert_eq!(pox_info.next_cycle.id, 15);
|
||||
assert_eq!(
|
||||
pox_info.reward_cycle_length as u32,
|
||||
pox_constants.reward_cycle_length
|
||||
@@ -2277,18 +2284,21 @@ fn pox_integration_test() {
|
||||
}
|
||||
|
||||
let pox_info = get_pox_info(&http_origin);
|
||||
|
||||
assert_eq!(
|
||||
&pox_info.contract_id,
|
||||
&format!("ST000000000000000000002AMW42H.pox")
|
||||
);
|
||||
assert_eq!(pox_info.first_burnchain_block_height, 0);
|
||||
assert_eq!(pox_info.next_cycle_cur_threshold, 125080000000000);
|
||||
assert_eq!(pox_info.cur_cycle_threshold, 125080000000000);
|
||||
assert_eq!(pox_info.cur_cycle_stacked_ustx, 1000000000000000);
|
||||
assert_eq!(pox_info.next_cycle_stacked_ustx, 2000000000000000);
|
||||
assert_eq!(pox_info.next_cycle.min_threshold_ustx, 125080000000000);
|
||||
assert_eq!(pox_info.current_cycle.min_threshold_ustx, 125080000000000);
|
||||
assert_eq!(pox_info.current_cycle.stacked_ustx, 1000000000000000);
|
||||
assert_eq!(pox_info.current_cycle.is_pox_active, false);
|
||||
assert_eq!(pox_info.next_cycle.stacked_ustx, 2000000000000000);
|
||||
assert_eq!(pox_info.reward_slots as u32, pox_constants.reward_slots());
|
||||
assert_eq!(pox_info.next_rewards_start, 225);
|
||||
assert_eq!(pox_info.next_prepare_phase_start, 235);
|
||||
assert_eq!(pox_info.next_cycle.reward_phase_start_block_height, 225);
|
||||
assert_eq!(pox_info.next_cycle.prepare_phase_start_block_height, 220);
|
||||
assert_eq!(pox_info.next_cycle.blocks_until_prepare_phase, -4);
|
||||
assert_eq!(
|
||||
pox_info.prepare_cycle_length as u32,
|
||||
pox_constants.prepare_length
|
||||
@@ -2298,6 +2308,8 @@ fn pox_integration_test() {
|
||||
pox_constants.pox_rejection_fraction
|
||||
);
|
||||
assert_eq!(pox_info.reward_cycle_id, 14);
|
||||
assert_eq!(pox_info.current_cycle.id, 14);
|
||||
assert_eq!(pox_info.next_cycle.id, 15);
|
||||
assert_eq!(
|
||||
pox_info.reward_cycle_length as u32,
|
||||
pox_constants.reward_cycle_length
|
||||
@@ -2323,6 +2335,21 @@ fn pox_integration_test() {
|
||||
eprintln!("Sort height: {}", sort_height);
|
||||
}
|
||||
|
||||
let pox_info = get_pox_info(&http_origin);
|
||||
|
||||
assert_eq!(
|
||||
&pox_info.contract_id,
|
||||
&format!("ST000000000000000000002AMW42H.pox")
|
||||
);
|
||||
assert_eq!(pox_info.first_burnchain_block_height, 0);
|
||||
assert_eq!(pox_info.current_cycle.min_threshold_ustx, 125080000000000);
|
||||
assert_eq!(pox_info.current_cycle.stacked_ustx, 2000000000000000);
|
||||
assert_eq!(pox_info.current_cycle.is_pox_active, true);
|
||||
assert_eq!(pox_info.next_cycle.reward_phase_start_block_height, 240);
|
||||
assert_eq!(pox_info.next_cycle.prepare_phase_start_block_height, 235);
|
||||
assert_eq!(pox_info.next_cycle.blocks_until_prepare_phase, -4);
|
||||
assert_eq!(pox_info.next_reward_cycle_in, 1);
|
||||
|
||||
// we should have received _seven_ Bitcoin commitments, because our commitment was 7 * threshold
|
||||
let utxos = btc_regtest_controller.get_all_utxos(&pox_pubkey);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user