diff --git a/cmd/info_cmd.go b/cmd/info_cmd.go index 6624d6bf01..999c0fce42 100644 --- a/cmd/info_cmd.go +++ b/cmd/info_cmd.go @@ -21,11 +21,12 @@ package cmd import ( "encoding/hex" "fmt" + "strconv" + "github.com/ontio/ontology/cmd/utils" "github.com/ontio/ontology/core/types" httpcom "github.com/ontio/ontology/http/base/common" "github.com/urfave/cli" - "strconv" ) var InfoCommand = cli.Command{ @@ -92,6 +93,16 @@ var InfoCommand = cli.Command{ utils.RPCPortFlag, }, }, + { + Action: getShardChainConfig, + Name: "shardChainConfig", + Usage: "Display chain config by shardID,block height", + ArgsUsage: "", + Description: `Display shard chain config by shardID,block height`, + Flags: []cli.Flag{ + utils.RPCPortFlag, + }, + }, }, Description: `Query information command can query information such as blocks, transactions, and transaction executions. You can use the ./Ontology info block --help command to view help information.`, @@ -257,3 +268,26 @@ func showTx(ctx *cli.Context) error { PrintJsonObject(txInfo) return nil } + +func getShardChainConfig(ctx *cli.Context) error { + SetRpcPort(ctx) + if ctx.NArg() < 2 { + PrintErrorMsg("Missing argument. shardID,height expected.") + cli.ShowSubcommandHelp(ctx) + return nil + } + shardID, err := strconv.ParseUint(ctx.Args().First(), 10, 64) + if err != nil { + return fmt.Errorf("ParseUint shardID error:%s", err) + } + height, err := strconv.ParseUint(ctx.Args().Get(1), 10, 32) + if err != nil { + return fmt.Errorf("ParseUint height error:%s", err) + } + chainConfig, err := utils.GetShardChainConfig(shardID, uint32(height)) + if err != nil { + return fmt.Errorf("GetShardChainConfig err:%s", err) + } + PrintJsonObject(chainConfig) + return nil +} diff --git a/cmd/utils/ont.go b/cmd/utils/ont.go index fbdcc32a21..dbde0f5789 100644 --- a/cmd/utils/ont.go +++ b/cmd/utils/ont.go @@ -36,6 +36,7 @@ import ( "github.com/ontio/ontology/common" "github.com/ontio/ontology/common/constants" "github.com/ontio/ontology/common/serialization" + vconfig "github.com/ontio/ontology/consensus/vbft/config" "github.com/ontio/ontology/core/payload" "github.com/ontio/ontology/core/signature" "github.com/ontio/ontology/core/types" @@ -621,6 +622,19 @@ func GetTxHeight(txHash string) (uint32, error) { return height, nil } +func GetShardChainConfig(shardID uint64, height uint32) (*vconfig.ChainConfig, error) { + data, ontErr := sendRpcRequest("getshardchainconfig", []interface{}{shardID, height}) + if ontErr != nil { + return nil, fmt.Errorf("getshardchainconfig shardID:%d,height:%d,err:%s", shardID, height, ontErr.Error) + } + cfg := &vconfig.ChainConfig{} + err := json.Unmarshal(data, cfg) + if err != nil { + return nil, fmt.Errorf("json.Unmarshal error:%s", err) + } + return cfg, nil +} + func DeployContract( gasPrice, gasLimit uint64, diff --git a/docs/specifications/restful_api_CN.md b/docs/specifications/restful_api_CN.md index 09ab06bb2e..2aba7a1983 100644 --- a/docs/specifications/restful_api_CN.md +++ b/docs/specifications/restful_api_CN.md @@ -49,6 +49,7 @@ | [get_grantong](#23-get_grantong) | GET /api/v1/grantong/:addr | 得到grant ong | | [get_shard_smtcode_evts](#24-get_shard_smtcode_evts) | GET /api/v1/shard/smartcode/event/txhash/:sourcetxhash | 通过source交易哈希得到该交易调用的shard交易的事件 | | [get_shard_tx_state](#25-get_shard_tx_state) | GET /api/v1/shardtxstate/:txhash/:notifyid | 通过txhash和notifyid查询txstate | +| [get_shard_chainconfig](#26-get_shard_chainconfig) | GET/api/v1/shardchainconfig/:shardid/:height| 得到 shardchainconfig | ### 1 get_conn_count @@ -1024,6 +1025,14 @@ curl -i http://127.0.0.1:30334/api/v1/shardtxstate/fb64410d900a237ee63502af33f68 } ``` +### 26 get_shard_chainconfig + +获取 shardchainconfig. + +GET +``` +/api/v1/shardchainconfig/:shardid/:height +``` ## 错误代码 | Field | Type | Description | diff --git a/docs/specifications/rpc_api.md b/docs/specifications/rpc_api.md index 4b8da32c37..96053d188d 100644 --- a/docs/specifications/rpc_api.md +++ b/docs/specifications/rpc_api.md @@ -99,7 +99,7 @@ There are some description of parameter used in rpc: | [getgrantong](#22-getgrantong) | | Get grant ong | | | [getshardsmartcodeevent](#23-getshardsmartcodeevent) | | Get shard smart contract event | | | [getshardtxstate](#24-getshardtxstate) | | Get tx state | | - +| [getshardchainconfig](#25-getshardchainconfig) | shardid,height | get chainconfig by shardid and height| | ### 1. getbestblockhash Get the hash of the highest height block in the main chain. @@ -1261,6 +1261,20 @@ Response: } ``` +#### 25. getshardchainconfig + +get shard chainconfig by shardid and height. + +#### Example + +``` +{ + "jsonrpc": "2.0", + "method": "getshardchainconfig", + "params": [1,12], + "id": 0 +} +``` ## Error Code diff --git a/docs/specifications/rpc_api_CN.md b/docs/specifications/rpc_api_CN.md index 9598bbc93e..61ec5a312a 100644 --- a/docs/specifications/rpc_api_CN.md +++ b/docs/specifications/rpc_api_CN.md @@ -99,6 +99,7 @@ | [getgrantong](#22-getgrantong) | | 获取 grant ong | | | [getshardsmartcodeevent](#23-getshardsmartcodeevent) | | 获取 shard smart contract event | | | [getshardtxstate](#24-getshardtxstate) | | 获取tx state | | +| [getshardchainconfig](#25-getshardchainconfig) | shardid,height | 获取指定shard chainconfig | | ### 1. getbestblockhash @@ -1273,6 +1274,23 @@ Response: } ``` +#### 25. getshardchainconfig + +获取指定shard chainconfig. + +#### Example + +Request: + +``` +{ + "jsonrpc": "2.0", + "method": "getshardchainconfig", + "params": [1,12], + "id": 0 +} +``` + ## 错误代码 错误码定义 diff --git a/docs/specifications/websocket_api.md b/docs/specifications/websocket_api.md index e6efcd1ddb..941c5fe9a9 100644 --- a/docs/specifications/websocket_api.md +++ b/docs/specifications/websocket_api.md @@ -51,6 +51,7 @@ This document describes the Websocket api format for the ws/wss used in the Onch | [getversion](#24-getversion) | | get the version information of the node | | [getnetworkid](#25-getnetworkid) | | get the network id | | [getgrantong](#26-getgrantong) | | get grant ong | +| [getshardchainconfig](#27-getshardchainconfig) |shardid,height | get shard chainconfig | ### 1. heartbeat If don't send heartbeat, the session expire after 5min. diff --git a/docs/specifications/websocket_api_CN.md b/docs/specifications/websocket_api_CN.md index 575cadc41a..debb3c5483 100644 --- a/docs/specifications/websocket_api_CN.md +++ b/docs/specifications/websocket_api_CN.md @@ -51,6 +51,7 @@ | [getversion](#24-getversion) | | 得到版本信息 | | [getnetworkid](#25-getnetworkid) | | 得到network id | | [getgrantong](#26-getgrantong) | | 得到grant ong | +| [getshardchainconfig](#27-getshardchainconfig) |shardid,height | 获取指定 shard chainconfig | ### 1. heartbeat diff --git a/http/base/actor/ledger.go b/http/base/actor/ledger.go index 8078e49463..8c7632e758 100644 --- a/http/base/actor/ledger.go +++ b/http/base/actor/ledger.go @@ -20,6 +20,8 @@ package actor import ( "github.com/ontio/ontology/common" + "github.com/ontio/ontology/consensus/utils" + vconfig "github.com/ontio/ontology/consensus/vbft/config" "github.com/ontio/ontology/core/chainmgr/xshard_state" "github.com/ontio/ontology/core/ledger" "github.com/ontio/ontology/core/payload" @@ -113,3 +115,12 @@ func GetEventNotifyByHeight(height uint32) ([]*event.ExecuteNotify, error) { func GetMerkleProof(proofHeight uint32, rootHeight uint32) ([]common.Uint256, error) { return ledger.DefLedger.GetMerkleProof(proofHeight, rootHeight) } + +//GetShardChainConfig +func GetShardChainConfig(shardID common.ShardID, height uint32) (*vconfig.ChainConfig, error) { + if ledger.DefLedger.ParentLedger != nil { + return utils.GetShardConfigByShardID(ledger.DefLedger.ParentLedger, shardID, height) + } else { + return nil, nil + } +} diff --git a/http/base/error/error.go b/http/base/error/error.go index 946b2071d8..a859b9b8fe 100644 --- a/http/base/error/error.go +++ b/http/base/error/error.go @@ -39,6 +39,7 @@ const ( UNKNOWN_ASSET int64 = 44002 UNKNOWN_BLOCK int64 = 44003 UNKNOWN_CONTRACT int64 = 44004 + UNKNOWN_CHAINCONFIG int64 = 44005 INTERNAL_ERROR int64 = 45001 SMARTCODE_ERROR int64 = 47001 diff --git a/http/base/rest/interfaces.go b/http/base/rest/interfaces.go index 32a9d157bc..015ec1c917 100644 --- a/http/base/rest/interfaces.go +++ b/http/base/rest/interfaces.go @@ -565,6 +565,36 @@ func GetShardTxState(cmd map[string]interface{}) map[string]interface{} { return resp } +func GetShardChainConfig(cmd map[string]interface{}) map[string]interface{} { + resp := ResponsePack(berr.SUCCESS) + idStr, ok := cmd["ShardID"].(string) + if !ok { + return ResponsePack(berr.INVALID_PARAMS) + } + id, err := strconv.ParseUint(idStr, 10, 64) + if err != nil { + return ResponsePack(berr.INVALID_PARAMS) + } + heightStr, ok := cmd["Height"].(string) + if !ok { + return ResponsePack(berr.INVALID_PARAMS) + } + height, err := strconv.ParseUint(heightStr, 10, 32) + if err != nil { + return ResponsePack(berr.INVALID_PARAMS) + } + shardID, err := common.NewShardID(id) + if err != nil { + return ResponsePack(berr.INTERNAL_ERROR) + } + chainConfig, err := bactor.GetShardChainConfig(shardID, uint32(height)) + if err != nil { + return ResponsePack(berr.INTERNAL_ERROR) + } + resp["Result"] = chainConfig + return resp +} + //get balance of address func GetBalance(cmd map[string]interface{}) map[string]interface{} { resp := ResponsePack(berr.SUCCESS) diff --git a/http/base/rpc/interfaces.go b/http/base/rpc/interfaces.go index a5e10323cf..591729d9d1 100644 --- a/http/base/rpc/interfaces.go +++ b/http/base/rpc/interfaces.go @@ -764,3 +764,34 @@ func GetGrantOng(params []interface{}) map[string]interface{} { } return responseSuccess(rsp) } + +//get shard chainconfig +func GetShardChainConfig(params []interface{}) map[string]interface{} { + if len(params) < 2 { + return responsePack(berr.INVALID_PARAMS, nil) + } + var shardID common.ShardID + var height uint32 + switch params[0].(type) { + case float64: + id := uint64(params[0].(float64)) + shardId, err := common.NewShardID(id) + if err != nil { + return responsePack(berr.INVALID_PARAMS, "") + } + shardID = shardId + default: + return responsePack(berr.INVALID_PARAMS, "") + } + switch params[1].(type) { + case float64: + height = uint32(params[1].(float64)) + default: + return responsePack(berr.INVALID_PARAMS, "") + } + chainConfig, err := bactor.GetShardChainConfig(shardID, height) + if err != nil { + return responsePack(berr.UNKNOWN_CHAINCONFIG, "") + } + return responseSuccess(chainConfig) +} diff --git a/http/jsonrpc/rpc_server.go b/http/jsonrpc/rpc_server.go index 3742e871a6..acb7102104 100644 --- a/http/jsonrpc/rpc_server.go +++ b/http/jsonrpc/rpc_server.go @@ -65,6 +65,7 @@ func StartRPCServer() error { rpc.HandleFunc("getshardstorage", rpc.GetShardStorage) rpc.HandleFunc("getshardtxstate", rpc.GetShardTxState) + rpc.HandleFunc("getshardchainconfig", rpc.GetShardChainConfig) err := http.ListenAndServe(":"+strconv.Itoa(int(cfg.DefConfig.Rpc.HttpJsonPort)), nil) if err != nil { return fmt.Errorf("ListenAndServe error:%s", err) diff --git a/http/restful/restful/server.go b/http/restful/restful/server.go index 2c7ff37b25..bcae101154 100644 --- a/http/restful/restful/server.go +++ b/http/restful/restful/server.go @@ -66,6 +66,7 @@ const ( GET_SHARD_STORAGE = "/api/v1/shardstorage/:shardid/:hash/:key" GET_SHARD_TX_STATE_NID = "/api/v1/shardtxstate/:txhash/:notifyid" GET_SHARD_TX_STATE = "/api/v1/shardtxstate/:txhash" + GET_SHARD_CHAIN_CONFIG = "/api/v1/shardchainconfig/:shardid/:height" GET_BALANCE = "/api/v1/balance/:addr" GET_CONTRACT_STATE = "/api/v1/contract/:hash" GET_SMTCOCE_EVT_TXS = "/api/v1/smartcode/event/transactions/:height" @@ -157,6 +158,7 @@ func (this *restServer) registryMethod() { GET_SHARD_STORAGE: {name: "getshardstorage", handler: rest.GetShardStorage}, GET_SHARD_TX_STATE_NID: {name: "getshardtxstate", handler: rest.GetShardTxState}, GET_SHARD_TX_STATE: {name: "getshardtxstate", handler: rest.GetShardTxState}, + GET_SHARD_CHAIN_CONFIG: {name: "getshardchainconfig", handler: rest.GetShardChainConfig}, GET_BALANCE: {name: "getbalance", handler: rest.GetBalance}, GET_ALLOWANCE: {name: "getallowance", handler: rest.GetAllowance}, GET_MERKLE_PROOF: {name: "getmerkleproof", handler: rest.GetMerkleProof}, @@ -205,6 +207,8 @@ func (this *restServer) getPath(url string) string { return GET_SHARD_TX_STATE_NID } else if strings.Contains(url, strings.TrimRight(GET_SHARD_TX_STATE, ":txhash")) { return GET_SHARD_TX_STATE + } else if strings.Contains(url, strings.TrimRight(GET_SHARD_CHAIN_CONFIG, ":shardid/:height")) { + return GET_SHARD_CHAIN_CONFIG } else if strings.Contains(url, strings.TrimRight(GET_STORAGE, ":hash/:key")) { return GET_STORAGE } else if strings.Contains(url, strings.TrimRight(GET_BALANCE, ":addr")) { @@ -250,6 +254,8 @@ func (this *restServer) getParams(r *http.Request, url string, req map[string]in req["TxHash"], req["NotifyId"] = getParam(r, "txhash"), getParam(r, "notifyid") case GET_SHARD_TX_STATE: req["TxHash"] = getParam(r, "txhash") + case GET_SHARD_CHAIN_CONFIG: + req["ShardID"], req["Height"] = getParam(r, "shardid"), getParam(r, "height") case GET_SMTCOCE_EVT_TXS: req["Height"] = getParam(r, "height") case GET_SMTCOCE_EVTS: diff --git a/http/websocket/websocket/server.go b/http/websocket/websocket/server.go index 429efe940f..11168b7551 100644 --- a/http/websocket/websocket/server.go +++ b/http/websocket/websocket/server.go @@ -197,6 +197,7 @@ func (self *WsServer) registryMethod() { "getstorage": {handler: rest.GetStorage}, "getshardstorage": {handler: rest.GetShardStorage}, "getshardtxstate": {handler: rest.GetShardTxState}, + "getshardchainconfig": {handler: rest.GetShardChainConfig}, "getallowance": {handler: rest.GetAllowance}, "getmerkleproof": {handler: rest.GetMerkleProof}, "getblocktxsbyheight": {handler: rest.GetBlockTxsByHeight},