main: Add invalidateblock and reconsiderblock rpc commands

The rpc calls and the rpchelp is added for the invalidateblock
and reconsiderblock methods on BlockChain.
This commit is contained in:
Calvin Kim 2023-01-03 18:52:25 +09:00 committed by Eugene Siegel
parent 1cb4d3a503
commit 0aa80ea8f7
3 changed files with 83 additions and 2 deletions

View File

@ -1419,3 +1419,38 @@ func (c *Client) GetDescriptorInfoAsync(descriptor string) FutureGetDescriptorIn
func (c *Client) GetDescriptorInfo(descriptor string) (*btcjson.GetDescriptorInfoResult, error) {
return c.GetDescriptorInfoAsync(descriptor).Receive()
}
// FutureReconsiderBlockResult is a future promise to deliver the result of a
// ReconsiderBlockAsync RPC invocation (or an applicable error).
type FutureReconsiderBlockResult chan *Response
// Receive waits for the Response promised by the future and returns the raw
// block requested from the server given its hash.
func (r FutureReconsiderBlockResult) Receive() error {
_, err := ReceiveFuture(r)
return err
}
// ReconsiderBlockAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See ReconsiderBlock for the blocking version and more details.
func (c *Client) ReconsiderBlockAsync(
blockHash *chainhash.Hash) FutureReconsiderBlockResult {
hash := ""
if blockHash != nil {
hash = blockHash.String()
}
cmd := btcjson.NewReconsiderBlockCmd(hash)
return c.SendCmd(cmd)
}
// ReconsiderBlock reconsiders an verifies a specific block and the branch that
// the block is included in. If the block is valid on reconsideration, the chain
// will reorg to that block if it has more PoW than the current tip.
func (c *Client) ReconsiderBlock(blockHash *chainhash.Hash) error {
return c.ReconsiderBlockAsync(blockHash).Receive()
}

View File

@ -170,8 +170,10 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
"getrawtransaction": handleGetRawTransaction,
"gettxout": handleGetTxOut,
"help": handleHelp,
"invalidateblock": handleInvalidateBlock,
"node": handleNode,
"ping": handlePing,
"reconsiderblock": handleReconsiderBlock,
"searchrawtransactions": handleSearchRawTransactions,
"sendrawtransaction": handleSendRawTransaction,
"setgenerate": handleSetGenerate,
@ -241,9 +243,7 @@ var rpcUnimplemented = map[string]struct{}{
"getmempoolentry": {},
"getnetworkinfo": {},
"getwork": {},
"invalidateblock": {},
"preciousblock": {},
"reconsiderblock": {},
}
// Commands that are available to a limited user
@ -284,6 +284,8 @@ var rpcLimited = map[string]struct{}{
"getrawmempool": {},
"getrawtransaction": {},
"gettxout": {},
"invalidateblock": {},
"reconsiderblock": {},
"searchrawtransactions": {},
"sendrawtransaction": {},
"submitblock": {},
@ -2850,6 +2852,23 @@ func handleGetTxOut(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (i
return txOutReply, nil
}
// handleInvalidateBlock implements the invalidateblock command.
func handleInvalidateBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
c := cmd.(*btcjson.InvalidateBlockCmd)
invalidateHash, err := chainhash.NewHashFromStr(c.BlockHash)
if err != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCDeserialization,
Message: fmt.Sprintf("Failed to deserialize blockhash from string of %s",
invalidateHash),
}
}
err = s.cfg.Chain.InvalidateBlock(invalidateHash)
return nil, err
}
// handleHelp implements the help command.
func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
c := cmd.(*btcjson.HelpCmd)
@ -3123,6 +3142,23 @@ func fetchMempoolTxnsForAddress(s *rpcServer, addr btcutil.Address, numToSkip, n
return mpTxns[numToSkip:rangeEnd], numToSkip
}
// handleReconsiderBlock implements the reconsiderblock command.
func handleReconsiderBlock(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
c := cmd.(*btcjson.ReconsiderBlockCmd)
reconsiderHash, err := chainhash.NewHashFromStr(c.BlockHash)
if err != nil {
return nil, &btcjson.RPCError{
Code: btcjson.ErrRPCDeserialization,
Message: fmt.Sprintf("Failed to deserialize blockhash from string of %s",
reconsiderHash),
}
}
err = s.cfg.Chain.ReconsiderBlock(reconsiderHash)
return nil, err
}
// handleSearchRawTransactions implements the searchrawtransactions command.
func handleSearchRawTransactions(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
// Respond with an error if the address index is not enabled.

View File

@ -544,6 +544,10 @@ var helpDescsEnUS = map[string]string{
"gettxout-vout": "The index of the output",
"gettxout-includemempool": "Include the mempool when true",
// InvalidateBlockCmd help.
"invalidateblock--synopsis": "Invalidates the block of the given block hash. To re-validate the invalidated block, use the reconsiderblock rpc",
"invalidateblock-blockhash": "The block hash of the block to invalidate",
// HelpCmd help.
"help--synopsis": "Returns a list of all commands or help for a specified command.",
"help-command": "The command to retrieve help for",
@ -681,6 +685,10 @@ var helpDescsEnUS = map[string]string{
"loadtxfilter-addresses": "Array of addresses to add to the transaction filter",
"loadtxfilter-outpoints": "Array of outpoints to add to the transaction filter",
// ReconsiderBlockCmd help.
"reconsiderblock--synopsis": "Reconsiders the block of the given block hash. Can be used to re-validate blocks invalidated with invalidateblock",
"reconsiderblock-blockhash": "The block hash of the block to reconsider",
// Rescan help.
"rescan--synopsis": "Rescan block chain for transactions to addresses.\n" +
"When the endblock parameter is omitted, the rescan continues through the best block in the main chain.\n" +
@ -788,7 +796,9 @@ var rpcResultTypes = map[string][]interface{}{
"gettxout": {(*btcjson.GetTxOutResult)(nil)},
"node": nil,
"help": {(*string)(nil), (*string)(nil)},
"invalidateblock": nil,
"ping": nil,
"reconsiderblock": nil,
"searchrawtransactions": {(*string)(nil), (*[]btcjson.SearchRawTransactionsResult)(nil)},
"sendrawtransaction": {(*string)(nil)},
"setgenerate": nil,