rpcserver: implement the getblockchaininfo RPC call
This commit is contained in:
parent
ec1c93ecc0
commit
7b0380cdd3
3 changed files with 158 additions and 10 deletions
4
glide.lock
generated
4
glide.lock
generated
|
@ -1,10 +1,10 @@
|
||||||
hash: 8f89ba1940f8798b8a0449810532e3f0bc552ed97d907bc3447a8941a2ea3a4a
|
hash: 8f89ba1940f8798b8a0449810532e3f0bc552ed97d907bc3447a8941a2ea3a4a
|
||||||
updated: 2016-10-26T22:53:00.0848822-05:00
|
updated: 2016-11-11T17:21:09.070085014-08:00
|
||||||
imports:
|
imports:
|
||||||
- name: github.com/btcsuite/btclog
|
- name: github.com/btcsuite/btclog
|
||||||
version: 73889fb79bd687870312b6e40effcecffbd57d30
|
version: 73889fb79bd687870312b6e40effcecffbd57d30
|
||||||
- name: github.com/btcsuite/btcrpcclient
|
- name: github.com/btcsuite/btcrpcclient
|
||||||
version: 2b780d16b042054d07aa322146194118fd7f7b81
|
version: c6e1d711da0db56803309479a5deabb02b816e88
|
||||||
- name: github.com/btcsuite/btcutil
|
- name: github.com/btcsuite/btcutil
|
||||||
version: aa9087a7efc961fbd253d4ae9c8b7a318749c273
|
version: aa9087a7efc961fbd253d4ae9c8b7a318749c273
|
||||||
subpackages:
|
subpackages:
|
||||||
|
|
123
rpcserver.go
123
rpcserver.go
|
@ -144,6 +144,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
||||||
"getbestblock": handleGetBestBlock,
|
"getbestblock": handleGetBestBlock,
|
||||||
"getbestblockhash": handleGetBestBlockHash,
|
"getbestblockhash": handleGetBestBlockHash,
|
||||||
"getblock": handleGetBlock,
|
"getblock": handleGetBlock,
|
||||||
|
"getblockchaininfo": handleGetBlockChainInfo,
|
||||||
"getblockcount": handleGetBlockCount,
|
"getblockcount": handleGetBlockCount,
|
||||||
"getblockhash": handleGetBlockHash,
|
"getblockhash": handleGetBlockHash,
|
||||||
"getblockheader": handleGetBlockHeader,
|
"getblockheader": handleGetBlockHeader,
|
||||||
|
@ -228,7 +229,6 @@ var rpcAskWallet = map[string]struct{}{
|
||||||
var rpcUnimplemented = map[string]struct{}{
|
var rpcUnimplemented = map[string]struct{}{
|
||||||
"estimatefee": {},
|
"estimatefee": {},
|
||||||
"estimatepriority": {},
|
"estimatepriority": {},
|
||||||
"getblockchaininfo": {},
|
|
||||||
"getchaintips": {},
|
"getchaintips": {},
|
||||||
"getnetworkinfo": {},
|
"getnetworkinfo": {},
|
||||||
"invalidateblock": {},
|
"invalidateblock": {},
|
||||||
|
@ -1121,6 +1121,127 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
|
||||||
return blockReply, nil
|
return blockReply, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// softForkStatus converts a ThresholdState state into a human readable string
|
||||||
|
// corresponding to the particular state.
|
||||||
|
func softForkStatus(state blockchain.ThresholdState) (string, error) {
|
||||||
|
switch state {
|
||||||
|
case blockchain.ThresholdDefined:
|
||||||
|
return "defined", nil
|
||||||
|
case blockchain.ThresholdStarted:
|
||||||
|
return "started", nil
|
||||||
|
case blockchain.ThresholdLockedIn:
|
||||||
|
return "lockedin", nil
|
||||||
|
case blockchain.ThresholdActive:
|
||||||
|
return "active", nil
|
||||||
|
case blockchain.ThresholdFailed:
|
||||||
|
return "failed", nil
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("unknown deployment state: %v", state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handleGetBlockChainInfo implements the getblockchaininfo command.
|
||||||
|
func handleGetBlockChainInfo(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
|
|
||||||
|
// Obtain a snapshot of the current best known blockchain state. We'll
|
||||||
|
// populate the response to this call primarily from this snapshot.
|
||||||
|
chainSnapshot := s.chain.BestSnapshot()
|
||||||
|
|
||||||
|
chainInfo := &btcjson.GetBlockChainInfoResult{
|
||||||
|
Chain: activeNetParams.Name,
|
||||||
|
Blocks: chainSnapshot.Height,
|
||||||
|
Headers: chainSnapshot.Height,
|
||||||
|
BestBlockHash: chainSnapshot.Hash.String(),
|
||||||
|
Difficulty: getDifficultyRatio(chainSnapshot.Bits),
|
||||||
|
MedianTime: chainSnapshot.MedianTime.Unix(),
|
||||||
|
Pruned: false,
|
||||||
|
Bip9SoftForks: make(map[string]*btcjson.Bip9SoftForkDescription),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, populate the response with information describing the current
|
||||||
|
// status of soft-forks deployed via the super-majority block
|
||||||
|
// signalling mechanism.
|
||||||
|
height := chainSnapshot.Height
|
||||||
|
chainInfo.SoftForks = []*btcjson.SoftForkDescription{
|
||||||
|
{
|
||||||
|
ID: "bip34",
|
||||||
|
Version: 2,
|
||||||
|
Reject: struct {
|
||||||
|
Status bool `json:"status"`
|
||||||
|
}{
|
||||||
|
Status: height >= activeNetParams.BIP0034Height,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "bip66",
|
||||||
|
Version: 3,
|
||||||
|
Reject: struct {
|
||||||
|
Status bool `json:"status"`
|
||||||
|
}{
|
||||||
|
Status: height >= activeNetParams.BIP0066Height,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "bip65",
|
||||||
|
Version: 4,
|
||||||
|
Reject: struct {
|
||||||
|
Status bool `json:"status"`
|
||||||
|
}{
|
||||||
|
Status: height >= activeNetParams.BIP0065Height,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, query the BIP0009 version bits state for all currently
|
||||||
|
// defined BIP0009 soft-fork deployments.
|
||||||
|
for deployment, deploymentDetails := range activeNetParams.Deployments {
|
||||||
|
// Map the integer deployment ID into a human readable
|
||||||
|
// fork-name.
|
||||||
|
var forkName string
|
||||||
|
switch deployment {
|
||||||
|
case chaincfg.DeploymentTestDummy:
|
||||||
|
forkName = "dummy"
|
||||||
|
default:
|
||||||
|
return nil, &btcjson.RPCError{
|
||||||
|
Code: btcjson.ErrRPCInternal.Code,
|
||||||
|
Message: fmt.Sprintf("Unknown deployment %v "+
|
||||||
|
"detected", deployment),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query the chain for the current status of the deployment as
|
||||||
|
// identified by its deployment ID.
|
||||||
|
deploymentStatus, err := s.chain.ThresholdState(uint32(deployment))
|
||||||
|
if err != nil {
|
||||||
|
context := "Failed to obtain deployment status"
|
||||||
|
return nil, internalRPCError(err.Error(), context)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attempt to convert the current deployment status into a
|
||||||
|
// human readable string. If the status is unrecognized, then a
|
||||||
|
// non-nil error is returned.
|
||||||
|
statusString, err := softForkStatus(deploymentStatus)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &btcjson.RPCError{
|
||||||
|
Code: btcjson.ErrRPCInternal.Code,
|
||||||
|
Message: fmt.Sprintf("unknown deployment status: %v",
|
||||||
|
deploymentStatus),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, populate the soft-fork description with all the
|
||||||
|
// information gathered above.
|
||||||
|
chainInfo.Bip9SoftForks[forkName] = &btcjson.Bip9SoftForkDescription{
|
||||||
|
Status: strings.ToLower(statusString),
|
||||||
|
Bit: deploymentDetails.BitNumber,
|
||||||
|
StartTime: int64(deploymentDetails.StartTime),
|
||||||
|
Timeout: int64(deploymentDetails.ExpireTime),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return chainInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleGetBlockCount implements the getblockcount command.
|
// handleGetBlockCount implements the getblockcount command.
|
||||||
func handleGetBlockCount(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
func handleGetBlockCount(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
best := s.chain.BestSnapshot()
|
best := s.chain.BestSnapshot()
|
||||||
|
|
|
@ -156,6 +156,32 @@ var helpDescsEnUS = map[string]string{
|
||||||
"getblock--condition1": "verbose=true",
|
"getblock--condition1": "verbose=true",
|
||||||
"getblock--result0": "Hex-encoded bytes of the serialized block",
|
"getblock--result0": "Hex-encoded bytes of the serialized block",
|
||||||
|
|
||||||
|
// GetBlockChainInfoCmd help.
|
||||||
|
"getblockchaininfo--synopsis": "Returns information about the current blockchain state and the status of any active soft-fork deployments.",
|
||||||
|
|
||||||
|
// GetBlockChainInfoResult help.
|
||||||
|
"getblockchaininforesult-chain": "The name of the chain the daemon is on (testnet, mainnet, etc)",
|
||||||
|
"getblockchaininforesult-blocks": "The number of blocks in the best known chain",
|
||||||
|
"getblockchaininforesult-headers": "The number of headers that we've gathered for in the best known chain",
|
||||||
|
"getblockchaininforesult-bestblockhash": "The block hash for the latest block in the main chain",
|
||||||
|
"getblockchaininforesult-difficulty": "The current chain difficulty",
|
||||||
|
"getblockchaininforesult-mediantime": "The median time from the PoV of the best block in the chain",
|
||||||
|
"getblockchaininforesult-verificationprogress": "An estimate for how much of the best chain we've verified",
|
||||||
|
"getblockchaininforesult-pruned": "A bool that indicates if the node is pruned or not",
|
||||||
|
"getblockchaininforesult-pruneheight": "The lowest block retained in the current pruned chain",
|
||||||
|
"getblockchaininforesult-chainwork": "The total cumulative work in the best chain",
|
||||||
|
"getblockchaininforesult-softforks": "The status of the super-majority soft-forks",
|
||||||
|
"getblockchaininforesult-bip9_softforks": "JSON object describing active BIP0009 deployments",
|
||||||
|
"getblockchaininforesult-bip9_softforks--key": "bip9_softforks",
|
||||||
|
"getblockchaininforesult-bip9_softforks--value": "An object describing a particular BIP009 deployment",
|
||||||
|
"getblockchaininforesult-bip9_softforks--desc": "The status of any defined BIP0009 soft-fork deployments",
|
||||||
|
|
||||||
|
// SoftForkDescription help.
|
||||||
|
"softforkdescription-reject": "The current activation status of the softfork",
|
||||||
|
"softforkdescription-version": "The block version that signals enforcement of this softfork",
|
||||||
|
"softforkdescription-id": "The string identifier for the soft fork",
|
||||||
|
"-status": "A bool which indicates if the soft fork is active",
|
||||||
|
|
||||||
// TxRawResult help.
|
// TxRawResult help.
|
||||||
"txrawresult-hex": "Hex-encoded transaction",
|
"txrawresult-hex": "Hex-encoded transaction",
|
||||||
"txrawresult-txid": "The hash of the transaction",
|
"txrawresult-txid": "The hash of the transaction",
|
||||||
|
@ -599,6 +625,7 @@ var rpcResultTypes = map[string][]interface{}{
|
||||||
"getblockhash": {(*string)(nil)},
|
"getblockhash": {(*string)(nil)},
|
||||||
"getblockheader": {(*string)(nil), (*btcjson.GetBlockHeaderVerboseResult)(nil)},
|
"getblockheader": {(*string)(nil), (*btcjson.GetBlockHeaderVerboseResult)(nil)},
|
||||||
"getblocktemplate": {(*btcjson.GetBlockTemplateResult)(nil), (*string)(nil), nil},
|
"getblocktemplate": {(*btcjson.GetBlockTemplateResult)(nil), (*string)(nil), nil},
|
||||||
|
"getblockchaininfo": {(*btcjson.GetBlockChainInfoResult)(nil)},
|
||||||
"getconnectioncount": {(*int32)(nil)},
|
"getconnectioncount": {(*int32)(nil)},
|
||||||
"getcurrentnet": {(*uint32)(nil)},
|
"getcurrentnet": {(*uint32)(nil)},
|
||||||
"getdifficulty": {(*float64)(nil)},
|
"getdifficulty": {(*float64)(nil)},
|
||||||
|
|
Loading…
Add table
Reference in a new issue