PoS RPC

Conflux中文社群發表於2022-01-07
idtitlecustom_edit_urlkeywords
pos_rpcPoS JSON RPChttps://github.com/Conflux-Ch...conflux
pos-rpc
sdk

conflux-rust 從 v2.0.0 開始引入 PoS finality 機制,用於加快區塊的最終性,從而防止 51% 攻擊。PoS finality 機制會引入一條獨立的 PoS 鏈,用於實現 PoS 共識,並對 PoW 區塊進行 finalize。相對應的 PoS 也有自己專門的 RPC 方法,用於獲取 PoS 鏈的資料。

目前只有 conflux-rust 的 archive node 可以對外提供 PoS RPC 服務,RPC 需要配置 public_rpc_apis 選項才能開啟。

可以在當前開啟的 RPC 方法組中,增加 pos 組。

public_rpc_apis = "safe,pos"

或者直接將 public_rpc_apis 設定為 all,開啟所有 RPC 方法。

public_rpc_apis = "all"

基本概念

epoch

PoS 中也有 epoch 的概念,可以理解為紀元。但跟 PoW 的 epoch 概念不太一樣。一個 epoch 代表一屆委員的任期,從 1 開始遞增,每個 epoch 平均對應一個小時, 每過一個 epoch,委員會中的部分委員會被替換。參與 PoS 共識獲得的獎勵也是按 epoch 來發放的。

round

round 中文翻譯為,PoS 鏈平均會每分鐘進行一輪共識,即嘗試產生一個 PoS 塊。亦即每個 epoch 會有 60 個 round,且每個新的 epoch, round 會重新從 1 開始。

注意:並不是每個 round 都會產生一個區塊,有可能會因為網路或共識失敗導致無法出塊。

block.number

block.number 也就是區塊的 height,每產生一個新的區塊,number 會加一。

PoS 區塊被某個委員會成員提議之後,會傳送到網路中進行投票,當區塊收集到足夠多的票數之後即為投票成功 voted,但此時區塊還沒被 commit,當三個 round 連續的區塊被產生後,最初的 round 對應的區塊會被提交,狀態變為 committed。

pivotDecision

pivotDecision 是 PoS 鏈對 PoW 鏈區塊的最終決定(final decision). 一旦 PoW 的某個區塊被 PoS 所引用,則代表該 PoW 區塊已經被 finalized,不會再發生 revert。PoS 鏈的區塊會包含 PivotDecision 資訊,表示該 PoS 區塊對 PoW 主軸鏈的某個區塊進行了 finalize。pivotDecision 資訊是 PoW 主軸鏈的某個區塊的 number 或者 hash。

PoS Address

PoS 賬戶地址跟 PoW 地址格式不同是一個 256 位 hash 值,例如:

0x046ca462890f25ed9394ca9f92c979ff48e1738a81822ecab96d83813c1a433c

PoS Model

AccountStatus

一個賬戶註冊參與 PoS 共識,或者增加質押的投票之後,票數首先會進入 inQueue 狀態,經過七天時間變為 locked 狀態。
當使用者發起解鎖操作之後,待解鎖的票券會先進入 outQueue 狀態,同樣需要經過七天時間變為 unlocked 狀態。

  • availableVotes: QUANTITY - 賬戶當前可用的票數, 等於 sum inQueue + locked
  • forfeited: QUANTITY - 賬戶被檢測到作惡時,staked 票數會被鎖死,無法提取的數量
  • forceRetired: [QUANTITY] - 賬戶被強制退休時的區塊數
  • inQueue: Array of VotesInQueue - 當前正在等待鎖定的佇列
  • locked: QUANTITY - 賬戶當前被鎖定的票數
  • outQueue: Array of VotesInQueue - 當前正在等待解鎖的佇列
  • unlocked: QUANTITY - 賬戶歷史累計解鎖的總票數

Decision

PoS 鏈對 PoW 主軸鏈的高度的決定, 被決定的 PoW 的區塊,即為 Finialized 的區塊

  • height: QUANTITY - 主軸區塊高度
  • blockHash: HASH - 主軸區塊雜湊

VotesInQueue

使用者正在等待鎖定或等待解鎖票權資訊。

  • endBlockNumber: QUANTITY - 狀態結束的區塊號
  • power: QUANTITY - 當前狀態票的數量

RPCs

pos_getStatus

返回 PoS 鏈當前的狀態資訊。

Parameters

Empty

Returns

Object - PoS status object.

  • epoch: QUANTITY - PoS 鏈當前的紀元號
  • latestCommitted: QUANTITY - 最新被 commit 的區塊號,commit 的區塊不會再發生 revert
  • latestVoted: [QUANTITY] - 最近被成功投票的區塊號。如果當前沒有完成投票的區塊為 null
  • pivotDecision: Decision - 當前 PoS 鏈所 finalize 的最新 PoW 鏈的決定

Example

Request

curl --location --request POST 'http://localhost:12537' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "pos_getStatus",
    "params": []
}'

Result

{
    "jsonrpc": "2.0",
    "result": {
        "epoch": "0x56",
        "latestCommitted": "0x140c",
        "latestVoted": "0x140e",
        "pivotDecision": {
          "height": "0x113af0",
          "blockHash": "0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"
        }
    },
    "id": 1
}

pos_getAccount

獲取 PoS 的賬戶資訊

Parameters

1.ADDRESS: 32 Bytes - PoS 賬戶地址
2.[QUANTITY]: 可選的 block number,用於查詢賬戶在某個區塊高度時的狀態

params: [
  "0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b",
  "0x100"
]

Returns

Object - 賬戶物件,或者 null(如果地址對應的賬戶不存在)

  • address: ADDRESS - 賬戶地址
  • blockNumber: QUANTITY - 狀態所對應的區塊號
  • status: OBJECT - 使用者當前的狀態資訊物件,參看 Account Status

Example

Request

curl --location --request POST 'http://localhost:12537' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "pos_getAccount",
    "params": ["0x046ca462890f25ed9394ca9f92c979ff48e1738a81822ecab96d83813c1a433c"]
}'

Response

{
    "jsonrpc": "2.0",
    "result": {
        "address": "0x046ca462890f25ed9394ca9f92c979ff48e1738a81822ecab96d83813c1a433c",
        "blockNumber": "0x14a7",
        "status": {
            "availableVotes": "0x513",
            "forfeited": "0x0",
            "forceRetired": null,
            "inQueue": [],
            "locked": "0x513",
            "outQueue": [],
            "unlocked": "0x0"
        }
    },
    "id": 1
}

pos_getCommittee

預設獲取當前的 PoS 委員會資訊,也可以通過指定 blockNumber 獲取歷史某個區塊時的委員會資訊。

Parameters

1.[QUANTITY]: 可選的 block number,用於查詢某個區塊高度時的委員會資訊

Returns

  • currentCommittee: OBJECT - 當前委員會成員, 參看 CurrentCommittee
  • elections: Array - 正在參選中的人員
CurrentCommittee

當前委員會資訊

  • epochNumber: QUANTITY - 委員會任期的 epoch 編號
  • nodes: Array of CommitteNode - 委員會成員列表
  • quorumVotingPower: QUANTITY - 區塊投票達到共識所需最低票數
  • totalVotingPower: QUANTITY - 本屆委員總共的票數
CommitteNode

委員資訊

  • address: ADDRESS - 賬戶地址
  • votingPower: QUANTITY - 票數
Election
  • isFinalized: BOOLEAN - 本輪選舉是否被確定
  • startBlockNumber: QUANTITY - 開始的區塊編號
  • topElectingNodes: Array of CommitteNode - 參選排名最靠前的 50 名使用者

Example

Request

curl --location --request POST 'http://localhost:12537' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "pos_getCommittee",
    "params": []
}'

Response

{
    "jsonrpc": "2.0",
    "result": {
        "currentCommittee": {
            "epochNumber": "0x5a",
            "nodes": [
                {
                    "address": "0x046ca462890f25ed9394ca9f92c979ff48e1738a81822ecab96d83813c1a433c",
                    "votingPower": "0xc8"
                },
                {
                    "address": "0x459b19e745eb410c3696ff1ed15f9de9bb46aa5fefc27b0b6e8b8d7aaadfe8c0",
                    "votingPower": "0x32"
                }
            ],
            "quorumVotingPower": "0xa7",
            "totalVotingPower": "0xfa"
        },
        "elections": [
            {
                "isFinalized": false,
                "startBlockNumber": "0x1518",
                "topElectingNodes": [
                    {
                        "address": "0x046ca462890f25ed9394ca9f92c979ff48e1738a81822ecab96d83813c1a433c",
                        "votingPower": "0x2a"
                    },
                    {
                        "address": "0x459b19e745eb410c3696ff1ed15f9de9bb46aa5fefc27b0b6e8b8d7aaadfe8c0",
                        "votingPower": "0x8"
                    }
                ]
            },
            {
                "isFinalized": false,
                "startBlockNumber": "0x1554",
                "topElectingNodes": []
            }
        ]
    },
    "id": 1
}

pos_getBlockByHash

根據 hash 獲取區塊資訊

Parameters

  1. HASH: 區塊 hash
params: [
  "0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"
]

Returns

  • epoch: QUANTITY - 區塊所在的紀元
  • hash: HASH - 區塊 hash
  • height: QUANTITY - 區塊高度
  • miner: [ADDRESS] - 區塊的建立者,可能為 null
  • nextTxNumber: QUANTITY - 下一區塊交易的其實編號
  • parentHash: HASH - 父區塊 hash
  • pivotDecision: Decision - 對 PoW 主軸鏈的決定
  • round: QUANTITY - 當前的輪次
  • signatures: Array of Signature - 區塊的簽名資訊
  • timestamp: QUANTITY - 時間戳
Signature

區塊簽名資訊

  • account: ADDRESS - 簽名的賬戶地址
  • votes: QUANTITY - 簽名賬戶的票數

Example

Request

curl --location --request POST 'http://localhost:12537' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "pos_getBlockByHash",
    "params": ["0x2b8b9d33e79e1735817a1278a9c8c5be828101b281bd4190531686153bee317b"]
}'

Response

{
    "jsonrpc": "2.0",
    "result": {
        "epoch": "0x5a",
        "hash": "0x2b8b9d33e79e1735817a1278a9c8c5be828101b281bd4190531686153bee317b",
        "height": "0x14ef",
        "miner": "0x046ca462890f25ed9394ca9f92c979ff48e1738a81822ecab96d83813c1a433c",
        "nextTxNumber": "0x1da7",
        "parentHash": "0x89cf3089296679dfef822d3dca037decab2a301de6f047e56c69cb34ae0b79e2",
        "pivotDecision": {
          "height": "0x113af0",
          "blockHash": "0x88df016429689c079f3b2f6ad39fa052532c56795b733da78a91ebe6a713944b"
        },
        "round": "0x13",
        "signatures": [
            {
                "account": "0x046ca462890f25ed9394ca9f92c979ff48e1738a81822ecab96d83813c1a433c",
                "votes": "0xc8"
            },
            {
                "account": "0x459b19e745eb410c3696ff1ed15f9de9bb46aa5fefc27b0b6e8b8d7aaadfe8c0",
                "votes": "0x32"
            }
        ],
        "timestamp": "0x5cce0e869522a"
    },
    "id": 1
}

pos_getBlockByNumber

根據區塊號獲取區塊資訊

Parameters

  1. QUANTITY|TAG: 區塊編號或者區塊TAG(latest_committed, latest_voted

Returns

pos_getBlockByHash 相同

Example

Request

curl --location --request POST 'http://localhost:12537' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "pos_getBlockByNumber",
    "params": ["0x14ef"]
}'

pos_getRewardsByEpoch

返回某個 PoS epoch 發放獎勵的具體資訊

Parameters

  1. QUANTITY: 紀元編號
params: [
  "0x4a"
]

Returns

  • accountRewards: Array of AccountReward
  • powEpochHash: HASH - 獎勵發放時 PoW 鏈主軸區塊的 hash
AccountReward
  • posAddress: ADDRESS - PoS 賬戶地址
  • powAddress: BASE32 - PoW 賬戶地址
  • reward: QUANTITY - 獲得的獎勵數量,單位為 Drip
Example

Request

curl --location --request POST 'http://localhost:12537' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "pos_getRewardsByEpoch",
    "params": ["0x4a"]
}'

Response

{
    "jsonrpc": "2.0",
    "result": {
        "accountRewards": [
            {
                "posAddress": "0x459b19e745eb410c3696ff1ed15f9de9bb46aa5fefc27b0b6e8b8d7aaadfe8c0",
                "powAddress": "NET8888:TYPE.USER:AAKSNR7XKKFFAM17MNESKAGU076T8FAG3YJ6PTHN16",
                "reward": "0x14931d20aa21eae3e6f"
            },
            {
                "posAddress": "0x046ca462890f25ed9394ca9f92c979ff48e1738a81822ecab96d83813c1a433c",
                "powAddress": "NET8888:TYPE.USER:AAPXUPNXG96GZ4077DAV0151K7P8498N9A6DMAWK1N",
                "reward": "0x2d49549e023888cd390"
            }
        ],
        "powEpochHash": "0x361cb0f19fd13c30da467d20a84ef01aabcd55e9812c5e2fd0721ea11a52e9f1"
    },
    "id": 1
}

pos_getTransactionByNumber

根據交易編號獲取交易資訊

Parameters

  1. QUANTITY: 交易編號
params: [
  "0x4a"
]

Returns

交易詳情

  • hash: HASH - 交易 hash
  • from: ADDRESS - 傳送方地址
  • number: QUANTITY - 交易號
  • blockHash: [HASH] - 交易所屬區塊 hash
  • blockNumber: [QUANTITY] - 交易所屬區塊編碼
  • payload: [OBJECT] - 交易主要資料,payload 內容根據交易型別不同而不同
  • status: [ENUM] - 交易的狀態,可能值:Executed, Failed, Discard
  • timestamp: [QUANTITY] - 交易時間戳
  • type: ENUM 交易的型別,可能值:BlockMetadata, Election, Retire, Register, UpdateVotingPower, PivoteDecision, Dispute, Other

payload 一共有六種 (BlockMetadata型別的交易 payload 為 null):

Register: 註冊

  • vrfPublicKey: STRING - VRF 公鑰
  • publicKey: STRING - 公鑰
{
  "publicKey": "0x90901cc921cd86c6a67bdb7652a3dc4e03e069c6ef6d8294eb4e856e396bb10e2191996a914eaaa9dfdaa75f2a3d70a3",
  "vrfPublicKey": "0x02a0c4e36a2e9a3a2804486b7c849d0eb6f30094e3fe91a9015e9c16f9279fbff8"
}

Election: 選舉

  • publicKey: STRING - 公鑰
  • targetTerm: QUANTITY - 計劃參選的委員會編號(epoch)
  • vrfProof: STRING - VRF 證明
  • vrfPublicKey: STRING - VRF 公鑰
{
  "publicKey": "0x8abc04b696da9699601c595cf3a9539e657262d42eef6b63fb324bb5b987418bf5491b04ed21edce4296174cb6d95fcc",
  "targetTerm": "0x7",
  "vrfProof": "0x03c09bec671c32ca143f67f3f965cf913993a53cc268f12954649d54548afe70e75c87fda23fbd01cd9e4af184aa06af01adfa0fce92697e811635190935cecf48aca9804a12e604df6f19455d1ca59f4f",
  "vrfPublicKey": "0x03862bbe4b6591457ebf5d410ab12fe8e9bebe80171a8d2f73db45c5933a8173a4"
}

UpdateVotingPower: 增加投票交易

  • address: HASH - PoS 賬號地址
  • votingPower: QUANTITY - 增加的票數
{
  "address": "0x52893f0ecd91f68b7db8a6eb04eb888b5ca1b208009eb9dfb434ad5da372f6f2",
  "votingPower": "0xb"
}

Retire: 退休投票

  • address: HASH - PoS 賬號地址
  • votingPower: QUANTITY - 退休的票數
{
  "address": "c70a93136ddff3023c4c5244c2be9141d242cdcb11d7ed15c053728c959b87bc",
  "votingPower": "0xa"
}

PivotDecision: 主軸區塊決定

  • height: QUANTITY - PoS 對 PoW 主軸決定的高度
  • blockHash: HASH - PoS 對 PoW 主軸決定的雜湊
{
  "blockHash": "0x0abf7b384d8bb02a98f21d1582e6d465b1e2382978d5473cbceb473039b0eef3",
  "height": "0x2900"
}

Dispute: 爭議

  • address: HASH - 賬戶地址
  • blsPublicKey: STRING - BLS 公鑰
  • vrfPublicKey: STRING - VRF 公鑰
  • conflictingVotes: ConflictingVotes - 有爭議的投票資訊

其中 ConflictingVotes 結構如下:

  • conflictVoteType: STRING - 爭議型別可能值為 proposal, vote
  • first: STRING - 第一個投票
  • second: STRING - 第二個投票
Example

Request

curl --location --request POST 'http://localhost:12537' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id": 1,
    "jsonrpc": "2.0",
    "method": "pos_getTransactionByNumber",
    "params": ["0x71"]
}'

Response

{
    "jsonrpc": "2.0",
    "result": {
        "blockHash": "0x355497700fc4c530c4eefa47c90deb052baaba4950934dfa6143f3c7321f3df1",
        "blockNumber": "0x3a",
        "from": "0x6f2e774cb8b83957d29e6a0b06551c11e632e1a0f46bee0d82b2fdc2b82fe4f9",
        "hash": "0x5505191e2f783e141fb8c84193829e494a27f197840987821514a12a0e04a10c",
        "number": "0x71",
        "payload": {
            "blockHash": "0xd66e1d6050d7070cab189a524782381e211508fa204a0674ea35fa1523cfba90",
            "height": "0x129"
        },
        "status": "Executed",
        "timestamp": "0x5cd05bea6a9b0",
        "type": "PivotDecision"
    },
    "id": 1
}

相關文章:

相關文章