From 871481ce1bdc0c42836be04e516c0878817cd7a2 Mon Sep 17 00:00:00 2001 From: David Hill Date: Wed, 15 Jan 2014 10:01:12 -0500 Subject: [PATCH] Implement submitblock. Closes #61. --- rpcserver.go | 32 +++++++++++++++++++++++++++++++- util/btcctl/btcctl.go | 11 +++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/rpcserver.go b/rpcserver.go index 5247c97f..54459f96 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -108,7 +108,7 @@ var rpcHandlers = map[string]commandHandler{ "signmessage": handleAskWallet, "signrawtransaction": handleAskWallet, "stop": handleStop, - "submitblock": handleUnimplemented, + "submitblock": handleSubmitBlock, "validateaddress": handleAskWallet, "verifychain": handleVerifyChain, "verifymessage": handleAskWallet, @@ -1062,6 +1062,36 @@ func handleStop(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) { return "btcd stopping.", nil } +// handleSubmitBlock implements the submitblock command. +func handleSubmitBlock(s *rpcServer, cmd btcjson.Cmd) (interface{}, error) { + c := cmd.(*btcjson.SubmitBlockCmd) + // Deserialize and send off to block processor. + serializedBlock, err := hex.DecodeString(c.HexBlock) + if err != nil { + err := btcjson.Error{ + Code: btcjson.ErrDeserialization.Code, + Message: "Block decode failed", + } + return nil, err + } + + block, err := btcutil.NewBlockFromBytes(serializedBlock) + if err != nil { + err := btcjson.Error{ + Code: btcjson.ErrDeserialization.Code, + Message: "Block decode failed", + } + return nil, err + } + + err = s.server.blockManager.blockChain.ProcessBlock(block, false) + if err != nil { + return fmt.Sprintf("rejected: %s", err.Error()), nil + } + + return nil, nil +} + func verifyChain(db btcdb.Db, level, depth int32) error { _, curheight64, err := db.NewestSha() if err != nil { diff --git a/util/btcctl/btcctl.go b/util/btcctl/btcctl.go index 5a254dc7..923ecdd0 100644 --- a/util/btcctl/btcctl.go +++ b/util/btcctl/btcctl.go @@ -69,6 +69,7 @@ var commandHandlers = map[string]*handlerData{ "verifychain": &handlerData{0, 2, displayJSONDump, []conversionHandler{toInt, toInt}, makeVerifyChain, "[level] [numblocks]"}, "sendrawtransaction": &handlerData{1, 0, displayGeneric, nil, makeSendRawTransaction, ""}, "stop": &handlerData{0, 0, displayGeneric, nil, makeStop, ""}, + "submitblock": &handlerData{1, 1, displayGeneric, nil, makeSubmitBlock, " [jsonparametersobject]"}, } // toInt attempts to convert the passed string to an integer. It returns the @@ -354,6 +355,16 @@ func makeStop(args []interface{}) (btcjson.Cmd, error) { return btcjson.NewStopCmd("btcctl") } +// makeSubmitBlock generates the cmd structure for submitblock commands. +func makeSubmitBlock(args []interface{}) (btcjson.Cmd, error) { + opts := &btcjson.SubmitBlockOptions{} + if len(args) == 2 { + opts.WorkId = args[1].(string) + } + + return btcjson.NewSubmitBlockCmd("btcctl", args[0].(string), opts) +} + // makeVerifyChain generates the cmd structure for verifychain comands. func makeVerifyChain(args []interface{}) (btcjson.Cmd, error) { iargs := make([]int32, 0, 2)