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
|
||||
updated: 2016-10-26T22:53:00.0848822-05:00
|
||||
updated: 2016-11-11T17:21:09.070085014-08:00
|
||||
imports:
|
||||
- name: github.com/btcsuite/btclog
|
||||
version: 73889fb79bd687870312b6e40effcecffbd57d30
|
||||
- name: github.com/btcsuite/btcrpcclient
|
||||
version: 2b780d16b042054d07aa322146194118fd7f7b81
|
||||
version: c6e1d711da0db56803309479a5deabb02b816e88
|
||||
- name: github.com/btcsuite/btcutil
|
||||
version: aa9087a7efc961fbd253d4ae9c8b7a318749c273
|
||||
subpackages:
|
||||
|
|
137
rpcserver.go
137
rpcserver.go
|
@ -144,6 +144,7 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
|||
"getbestblock": handleGetBestBlock,
|
||||
"getbestblockhash": handleGetBestBlockHash,
|
||||
"getblock": handleGetBlock,
|
||||
"getblockchaininfo": handleGetBlockChainInfo,
|
||||
"getblockcount": handleGetBlockCount,
|
||||
"getblockhash": handleGetBlockHash,
|
||||
"getblockheader": handleGetBlockHeader,
|
||||
|
@ -226,14 +227,13 @@ var rpcAskWallet = map[string]struct{}{
|
|||
|
||||
// Commands that are currently unimplemented, but should ultimately be.
|
||||
var rpcUnimplemented = map[string]struct{}{
|
||||
"estimatefee": {},
|
||||
"estimatepriority": {},
|
||||
"getblockchaininfo": {},
|
||||
"getchaintips": {},
|
||||
"getnetworkinfo": {},
|
||||
"invalidateblock": {},
|
||||
"preciousblock": {},
|
||||
"reconsiderblock": {},
|
||||
"estimatefee": {},
|
||||
"estimatepriority": {},
|
||||
"getchaintips": {},
|
||||
"getnetworkinfo": {},
|
||||
"invalidateblock": {},
|
||||
"preciousblock": {},
|
||||
"reconsiderblock": {},
|
||||
}
|
||||
|
||||
// Commands that are available to a limited user
|
||||
|
@ -1121,6 +1121,127 @@ func handleGetBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
|
|||
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.
|
||||
func handleGetBlockCount(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||
best := s.chain.BestSnapshot()
|
||||
|
|
|
@ -156,6 +156,32 @@ var helpDescsEnUS = map[string]string{
|
|||
"getblock--condition1": "verbose=true",
|
||||
"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-hex": "Hex-encoded transaction",
|
||||
"txrawresult-txid": "The hash of the transaction",
|
||||
|
@ -599,6 +625,7 @@ var rpcResultTypes = map[string][]interface{}{
|
|||
"getblockhash": {(*string)(nil)},
|
||||
"getblockheader": {(*string)(nil), (*btcjson.GetBlockHeaderVerboseResult)(nil)},
|
||||
"getblocktemplate": {(*btcjson.GetBlockTemplateResult)(nil), (*string)(nil), nil},
|
||||
"getblockchaininfo": {(*btcjson.GetBlockChainInfoResult)(nil)},
|
||||
"getconnectioncount": {(*int32)(nil)},
|
||||
"getcurrentnet": {(*uint32)(nil)},
|
||||
"getdifficulty": {(*float64)(nil)},
|
||||
|
|
Loading…
Reference in a new issue