Add support for the verifychain command.
So far we only do level 0 and level 1 checks (precense and basic sanity). The checks done at higher levels in bitcoind are closely coupled with their database layout. arguably Closes #13
This commit is contained in:
parent
31f27cffd5
commit
bb276b53aa
2 changed files with 65 additions and 1 deletions
57
rpcserver.go
57
rpcserver.go
|
@ -466,7 +466,7 @@ var handlers = map[string]commandHandler{
|
|||
"stop": handleStop,
|
||||
"submitblock": handleUnimplemented,
|
||||
"validateaddress": handleAskWallet,
|
||||
"verifychain": handleUnimplemented,
|
||||
"verifychain": handleVerifyChain,
|
||||
"verifymessage": handleAskWallet,
|
||||
"walletlock": handleAskWallet,
|
||||
"walletpassphrase": handleAskWallet,
|
||||
|
@ -819,6 +819,61 @@ func handleStop(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byte) (
|
|||
return "btcd stopping.", nil
|
||||
}
|
||||
|
||||
func verifyChain(db btcdb.Db, level, depth int32) error {
|
||||
_, curheight64, err := db.NewestSha()
|
||||
if err != nil {
|
||||
log.Errorf("RPCS: verify is unable to fetch current block "+
|
||||
"height: %v", err)
|
||||
}
|
||||
|
||||
curheight := int32(curheight64)
|
||||
|
||||
if depth > curheight {
|
||||
depth = curheight
|
||||
}
|
||||
|
||||
for height := curheight; height > (curheight - depth); height-- {
|
||||
// Level 0 just looks up the block.
|
||||
sha, err := db.FetchBlockShaByHeight(int64(height))
|
||||
if err != nil {
|
||||
log.Errorf("RPCS: verify is unable to fetch block at "+
|
||||
"height %d: %v", height, err)
|
||||
return err
|
||||
}
|
||||
|
||||
block, err := db.FetchBlockBySha(sha)
|
||||
if err != nil {
|
||||
log.Errorf("RPCS: verify is unable to fetch block at "+
|
||||
"sha %v height %d: %v", sha, height, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Level 1 does basic chain sanity checks.
|
||||
if level > 0 {
|
||||
err := btcchain.CheckBlockSanity(block,
|
||||
activeNetParams.powLimit)
|
||||
if err != nil {
|
||||
log.Errorf("RPCS: verify is unable to "+
|
||||
"validate block at sha %v height "+
|
||||
"%s: %v", sha, height, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Infof("RPCS: Chain verify completed successfully")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleVerifyChain(s *rpcServer, cmd btcjson.Cmd, walletNotification chan []byte) (interface{}, error) {
|
||||
c := cmd.(*btcjson.VerifyChainCmd)
|
||||
|
||||
err := verifyChain(s.server.db, c.CheckLevel, c.CheckDepth)
|
||||
if err != nil {
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// parseCmd parses a marshaled known command, returning any errors as a
|
||||
// btcjson.Error that can be used in replies. The returned cmd may still
|
||||
// be non-nil if b is at least a valid marshaled JSON-RPC message.
|
||||
|
|
|
@ -60,6 +60,7 @@ var commandHandlers = map[string]*handlerData{
|
|||
"getpeerinfo": &handlerData{0, 0, displaySpewDump, nil, makeGetPeerInfo, ""},
|
||||
"getrawmempool": &handlerData{0, 0, displaySpewDump, nil, makeGetRawMempool, ""},
|
||||
"getrawtransaction": &handlerData{1, 1, displaySpewDump, []conversionHandler{nil, toInt}, makeGetRawTransaction, "<txhash> [verbose=0]"},
|
||||
"verifychain": &handlerData{0, 2, displaySpewDump, []conversionHandler{toInt, toInt}, makeVerifyChain, "[level] [depth]"},
|
||||
"stop": &handlerData{0, 0, displayGeneric, nil, makeStop, ""},
|
||||
}
|
||||
|
||||
|
@ -192,6 +193,14 @@ func makeStop(args []interface{}) (btcjson.Cmd, error) {
|
|||
return btcjson.NewStopCmd("btcctl")
|
||||
}
|
||||
|
||||
func makeVerifyChain(args []interface{}) (btcjson.Cmd, error) {
|
||||
iargs := make([]int32, 0, 2)
|
||||
for _, i := range args {
|
||||
iargs = append(iargs, int32(i.(int)))
|
||||
}
|
||||
return btcjson.NewVerifyChainCmd("btcctl", iargs...)
|
||||
}
|
||||
|
||||
// send sends a JSON-RPC command to the specified RPC server and examines the
|
||||
// results for various error conditions. It either returns a valid result or
|
||||
// an appropriate error.
|
||||
|
|
Loading…
Add table
Reference in a new issue