rpc implement setban
, listbanned
, clearbanned
#85
7 changed files with 371 additions and 11 deletions
|
@ -48,6 +48,15 @@ func NewAddNodeCmd(addr string, subCmd AddNodeSubCmd) *AddNodeCmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClearBannedCmd defines the clearbanned JSON-RPC command.
|
||||||
|
type ClearBannedCmd struct{}
|
||||||
|
|
||||||
|
// NewClearBannedCmd returns a new instance which can be used to issue an clearbanned
|
||||||
|
// JSON-RPC command.
|
||||||
|
func NewClearBannedCmd() *ClearBannedCmd {
|
||||||
|
return &ClearBannedCmd{}
|
||||||
|
}
|
||||||
|
|
||||||
// TransactionInput represents the inputs to a transaction. Specifically a
|
// TransactionInput represents the inputs to a transaction. Specifically a
|
||||||
// transaction hash and output number pair.
|
// transaction hash and output number pair.
|
||||||
type TransactionInput struct {
|
type TransactionInput struct {
|
||||||
|
@ -757,6 +766,15 @@ func NewInvalidateBlockCmd(blockHash string) *InvalidateBlockCmd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListBannedCmd defines the listbanned JSON-RPC command.
|
||||||
|
type ListBannedCmd struct{}
|
||||||
|
|
||||||
|
// NewListBannedCmd returns a new instance which can be used to issue a listbanned
|
||||||
|
// JSON-RPC command.
|
||||||
|
func NewListBannedCmd() *ListBannedCmd {
|
||||||
|
return &ListBannedCmd{}
|
||||||
|
}
|
||||||
|
|
||||||
// PingCmd defines the ping JSON-RPC command.
|
// PingCmd defines the ping JSON-RPC command.
|
||||||
type PingCmd struct{}
|
type PingCmd struct{}
|
||||||
|
|
||||||
|
@ -903,6 +921,39 @@ func NewBitcoindSendRawTransactionCmd(hexTx string, maxFeeRate int32) *SendRawTr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetBanSubCmd defines the type used in the setban JSON-RPC command for the
|
||||||
|
// sub command field.
|
||||||
|
type SetBanSubCmd string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SBAdd indicates the specified host should be added as a persistent
|
||||||
|
// peer.
|
||||||
|
SBAdd SetBanSubCmd = "add"
|
||||||
|
|
||||||
|
// SBRemove indicates the specified peer should be removed.
|
||||||
|
SBRemove SetBanSubCmd = "remove"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SetBanCmd defines the setban JSON-RPC command.
|
||||||
|
type SetBanCmd struct {
|
||||||
|
Addr string
|
||||||
|
SubCmd SetBanSubCmd `jsonrpcusage:"\"add|remove\""`
|
||||||
|
BanTime *int `jsonrpcdefault:"0"`
|
||||||
|
Absolute *bool `jsonrpcdefault:"false"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSetBanCmd returns a new instance which can be used to issue an setban
|
||||||
|
// JSON-RPC command.
|
||||||
|
func NewSetBanCmd(addr string, subCmd SetBanSubCmd, banTime *int,
|
||||||
|
absolute *bool) *SetBanCmd {
|
||||||
|
return &SetBanCmd{
|
||||||
|
Addr: addr,
|
||||||
|
SubCmd: subCmd,
|
||||||
|
BanTime: banTime,
|
||||||
|
Absolute: absolute,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// SetGenerateCmd defines the setgenerate JSON-RPC command.
|
// SetGenerateCmd defines the setgenerate JSON-RPC command.
|
||||||
type SetGenerateCmd struct {
|
type SetGenerateCmd struct {
|
||||||
Generate bool
|
Generate bool
|
||||||
|
@ -1080,6 +1131,9 @@ func init() {
|
||||||
MustRegisterCmd("getnetworkhashps", (*GetNetworkHashPSCmd)(nil), flags)
|
MustRegisterCmd("getnetworkhashps", (*GetNetworkHashPSCmd)(nil), flags)
|
||||||
MustRegisterCmd("getnodeaddresses", (*GetNodeAddressesCmd)(nil), flags)
|
MustRegisterCmd("getnodeaddresses", (*GetNodeAddressesCmd)(nil), flags)
|
||||||
MustRegisterCmd("getpeerinfo", (*GetPeerInfoCmd)(nil), flags)
|
MustRegisterCmd("getpeerinfo", (*GetPeerInfoCmd)(nil), flags)
|
||||||
|
MustRegisterCmd("listbanned", (*ListBannedCmd)(nil), flags)
|
||||||
|
MustRegisterCmd("setban", (*SetBanCmd)(nil), flags)
|
||||||
|
MustRegisterCmd("clearbanned", (*ClearBannedCmd)(nil), flags)
|
||||||
MustRegisterCmd("getrawmempool", (*GetRawMempoolCmd)(nil), flags)
|
MustRegisterCmd("getrawmempool", (*GetRawMempoolCmd)(nil), flags)
|
||||||
MustRegisterCmd("getrawtransaction", (*GetRawTransactionCmd)(nil), flags)
|
MustRegisterCmd("getrawtransaction", (*GetRawTransactionCmd)(nil), flags)
|
||||||
MustRegisterCmd("gettxout", (*GetTxOutCmd)(nil), flags)
|
MustRegisterCmd("gettxout", (*GetTxOutCmd)(nil), flags)
|
||||||
|
|
|
@ -721,6 +721,15 @@ type InfoChainResult struct {
|
||||||
Errors string `json:"errors"`
|
Errors string `json:"errors"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListBannedResult models the data returned from the listbanned command.
|
||||||
|
type ListBannedResult struct {
|
||||||
|
Address string `json:"address"`
|
||||||
|
BanCreated int64 `json:"ban_created"`
|
||||||
|
BannedUntil int64 `json:"banned_until"`
|
||||||
|
BanDuration int64 `json:"ban_duration"`
|
||||||
|
TimeRemaining int64 `json:"time_remaining"`
|
||||||
|
}
|
||||||
|
|
||||||
// TxRawResult models the data from the getrawtransaction command.
|
// TxRawResult models the data from the getrawtransaction command.
|
||||||
type TxRawResult struct {
|
type TxRawResult struct {
|
||||||
Hex string `json:"hex"`
|
Hex string `json:"hex"`
|
||||||
|
|
|
@ -6,6 +6,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/lbryio/lbcd/blockchain"
|
"github.com/lbryio/lbcd/blockchain"
|
||||||
"github.com/lbryio/lbcd/chaincfg/chainhash"
|
"github.com/lbryio/lbcd/chaincfg/chainhash"
|
||||||
|
@ -181,6 +182,57 @@ func (cm *rpcConnManager) ConnectedPeers() []rpcserverPeer {
|
||||||
return peers
|
return peers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BannedPeers returns a map consisting of all banned host with banned period.
|
||||||
|
//
|
||||||
|
// This function is safe for concurrent access and is part of the
|
||||||
|
// rpcserverConnManager interface implementation.
|
||||||
|
func (cm *rpcConnManager) BannedPeers() map[string]bannedPeriod {
|
||||||
|
replyChan := make(chan map[string]bannedPeriod)
|
||||||
|
cm.server.query <- listBannedPeersMsg{reply: replyChan}
|
||||||
|
return <-replyChan
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBan removes the peer associated with the provided address from the
|
||||||
|
// list of persistent peers.
|
||||||
|
//
|
||||||
|
// This function is safe for concurrent access and is part of the
|
||||||
|
// rpcserverConnManager interface implementation.
|
||||||
|
func (cm *rpcConnManager) SetBan(addr string, since, until time.Time) error {
|
||||||
|
replyChan := make(chan error)
|
||||||
|
cm.server.query <- setBanMsg{
|
||||||
|
addr: addr,
|
||||||
|
since: since,
|
||||||
|
until: until,
|
||||||
|
reply: replyChan,
|
||||||
|
}
|
||||||
|
return <-replyChan
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveBan removes a host from banned list.
|
||||||
|
//
|
||||||
|
// This function is safe for concurrent access and is part of the
|
||||||
|
// rpcserverConnManager interface implementation.
|
||||||
|
func (cm *rpcConnManager) RemoveBan(addr string) error {
|
||||||
|
replyChan := make(chan error)
|
||||||
|
cm.server.query <- removeBanMsg{
|
||||||
|
addr: addr,
|
||||||
|
reply: replyChan,
|
||||||
|
}
|
||||||
|
return <-replyChan
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearBanned removes all banned host with banned period.
|
||||||
|
//
|
||||||
|
// This function is safe for concurrent access and is part of the
|
||||||
|
// rpcserverConnManager interface implementation.
|
||||||
|
func (cm *rpcConnManager) ClearBanned() error {
|
||||||
|
replyChan := make(chan error)
|
||||||
|
cm.server.query <- clearBannedMsg{
|
||||||
|
reply: replyChan,
|
||||||
|
}
|
||||||
|
return <-replyChan
|
||||||
|
}
|
||||||
|
|
||||||
// PersistentPeers returns an array consisting of all the added persistent
|
// PersistentPeers returns an array consisting of all the added persistent
|
||||||
// peers.
|
// peers.
|
||||||
//
|
//
|
||||||
|
|
|
@ -355,6 +355,75 @@ func (c *Client) GetPeerInfo() ([]btcjson.GetPeerInfoResult, error) {
|
||||||
return c.GetPeerInfoAsync().Receive()
|
return c.GetPeerInfoAsync().Receive()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FutureListBannedResult is a future promise to deliver the result of a
|
||||||
|
// ListBannedAsync RPC invocation (or an applicable error).
|
||||||
|
type FutureListBannedResult chan *Response
|
||||||
|
|
||||||
|
// Receive waits for the Response promised by the future and returns data about
|
||||||
|
// each connected network peer.
|
||||||
|
func (r FutureListBannedResult) Receive() ([]btcjson.ListBannedResult, error) {
|
||||||
|
res, err := ReceiveFuture(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmarshal result as an array of ListBanned result objects.
|
||||||
|
var bannedPeers []btcjson.ListBannedResult
|
||||||
|
err = json.Unmarshal(res, &bannedPeers)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return bannedPeers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBanCommand enumerates the available commands that the SetBanCommand function
|
||||||
|
// accepts.
|
||||||
|
type SetBanCommand string
|
||||||
|
|
||||||
|
// Constants used to indicate the command for the SetBanCommand function.
|
||||||
|
const (
|
||||||
|
// SBAdd indicates the specified host should be added as a banned
|
||||||
|
// peer.
|
||||||
|
SBAdd SetBanCommand = "add"
|
||||||
|
|
||||||
|
// SBRemove indicates the specified peer should be removed.
|
||||||
|
SBRemove SetBanCommand = "remove"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the SetBanCommand in human-readable form.
|
||||||
|
func (cmd SetBanCommand) String() string {
|
||||||
|
return string(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FutureSetBanResult is a future promise to deliver the result of an
|
||||||
|
// SetBanAsync RPC invocation (or an applicable error).
|
||||||
|
type FutureSetBanResult chan *Response
|
||||||
|
|
||||||
|
// Receive waits for the Response promised by the future and returns an error if
|
||||||
|
// any occurred when performing the specified command.
|
||||||
|
func (r FutureSetBanResult) Receive() error {
|
||||||
|
_, err := ReceiveFuture(r)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBanAsync 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.
|
||||||
|
func (c *Client) SetBanAsync(addr string, command string, banTime *int,
|
||||||
|
absolute *bool) FutureSetBanResult {
|
||||||
|
cmd := btcjson.NewSetBanCmd(addr, btcjson.SetBanSubCmd(command), banTime,
|
||||||
|
absolute)
|
||||||
|
return c.SendCmd(cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBan attempts to perform the passed command on the passed persistent peer.
|
||||||
|
// For example, it can be used to add or a remove a banned peer.
|
||||||
|
func (c *Client) SetBan(addr string, command string, banTime *int,
|
||||||
|
absolute *bool) error {
|
||||||
|
return c.SetBanAsync(addr, command, banTime, absolute).Receive()
|
||||||
|
}
|
||||||
|
|
||||||
// FutureGetNetTotalsResult is a future promise to deliver the result of a
|
// FutureGetNetTotalsResult is a future promise to deliver the result of a
|
||||||
// GetNetTotalsAsync RPC invocation (or an applicable error).
|
// GetNetTotalsAsync RPC invocation (or an applicable error).
|
||||||
type FutureGetNetTotalsResult chan *Response
|
type FutureGetNetTotalsResult chan *Response
|
||||||
|
|
105
rpcserver.go
105
rpcserver.go
|
@ -134,6 +134,7 @@ type commandHandler func(*rpcServer, interface{}, <-chan struct{}) (interface{},
|
||||||
var rpcHandlers map[string]commandHandler
|
var rpcHandlers map[string]commandHandler
|
||||||
var rpcHandlersBeforeInit = map[string]commandHandler{
|
var rpcHandlersBeforeInit = map[string]commandHandler{
|
||||||
"addnode": handleAddNode,
|
"addnode": handleAddNode,
|
||||||
|
"clearbanned": handleClearBanned,
|
||||||
"createrawtransaction": handleCreateRawTransaction,
|
"createrawtransaction": handleCreateRawTransaction,
|
||||||
"debuglevel": handleDebugLevel,
|
"debuglevel": handleDebugLevel,
|
||||||
"decoderawtransaction": handleDecodeRawTransaction,
|
"decoderawtransaction": handleDecodeRawTransaction,
|
||||||
|
@ -150,10 +151,10 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
||||||
"getblockcount": handleGetBlockCount,
|
"getblockcount": handleGetBlockCount,
|
||||||
"getblockhash": handleGetBlockHash,
|
"getblockhash": handleGetBlockHash,
|
||||||
"getblockheader": handleGetBlockHeader,
|
"getblockheader": handleGetBlockHeader,
|
||||||
"getchaintips": handleGetChainTips,
|
|
||||||
"getblocktemplate": handleGetBlockTemplate,
|
"getblocktemplate": handleGetBlockTemplate,
|
||||||
"getcfilter": handleGetCFilter,
|
"getcfilter": handleGetCFilter,
|
||||||
"getcfilterheader": handleGetCFilterHeader,
|
"getcfilterheader": handleGetCFilterHeader,
|
||||||
|
"getchaintips": handleGetChainTips,
|
||||||
"getconnectioncount": handleGetConnectionCount,
|
"getconnectioncount": handleGetConnectionCount,
|
||||||
"getcurrentnet": handleGetCurrentNet,
|
"getcurrentnet": handleGetCurrentNet,
|
||||||
"getdifficulty": handleGetDifficulty,
|
"getdifficulty": handleGetDifficulty,
|
||||||
|
@ -161,8 +162,8 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
||||||
"gethashespersec": handleGetHashesPerSec,
|
"gethashespersec": handleGetHashesPerSec,
|
||||||
"getheaders": handleGetHeaders,
|
"getheaders": handleGetHeaders,
|
||||||
"getinfo": handleGetInfo,
|
"getinfo": handleGetInfo,
|
||||||
"getmempoolinfo": handleGetMempoolInfo,
|
|
||||||
"getmempoolentry": handleGetMempoolEntry,
|
"getmempoolentry": handleGetMempoolEntry,
|
||||||
|
"getmempoolinfo": handleGetMempoolInfo,
|
||||||
"getmininginfo": handleGetMiningInfo,
|
"getmininginfo": handleGetMiningInfo,
|
||||||
"getnettotals": handleGetNetTotals,
|
"getnettotals": handleGetNetTotals,
|
||||||
"getnetworkhashps": handleGetNetworkHashPS,
|
"getnetworkhashps": handleGetNetworkHashPS,
|
||||||
|
@ -174,11 +175,13 @@ var rpcHandlersBeforeInit = map[string]commandHandler{
|
||||||
"gettxout": handleGetTxOut,
|
"gettxout": handleGetTxOut,
|
||||||
"help": handleHelp,
|
"help": handleHelp,
|
||||||
"invalidateblock": handleInvalidateBlock,
|
"invalidateblock": handleInvalidateBlock,
|
||||||
|
"listbanned": handleListBanned,
|
||||||
"node": handleNode,
|
"node": handleNode,
|
||||||
"ping": handlePing,
|
"ping": handlePing,
|
||||||
"reconsiderblock": handleReconsiderBlock,
|
"reconsiderblock": handleReconsiderBlock,
|
||||||
"searchrawtransactions": handleSearchRawTransactions,
|
"searchrawtransactions": handleSearchRawTransactions,
|
||||||
"sendrawtransaction": handleSendRawTransaction,
|
"sendrawtransaction": handleSendRawTransaction,
|
||||||
|
"setban": handleSetBan,
|
||||||
"setgenerate": handleSetGenerate,
|
"setgenerate": handleSetGenerate,
|
||||||
"signmessagewithprivkey": handleSignMessageWithPrivKey,
|
"signmessagewithprivkey": handleSignMessageWithPrivKey,
|
||||||
"stop": handleStop,
|
"stop": handleStop,
|
||||||
|
@ -398,6 +401,21 @@ func handleAddNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (in
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleClearBanned handles clearbanned commands.
|
||||||
|
func handleClearBanned(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
|
|
||||||
|
err := s.cfg.ConnMgr.ClearBanned()
|
||||||
|
if err != nil {
|
||||||
|
return nil, &btcjson.RPCError{
|
||||||
|
Code: btcjson.ErrRPCInvalidParameter,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no data returned unless an error.
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleNode handles node commands.
|
// handleNode handles node commands.
|
||||||
func handleNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
func handleNode(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.NodeCmd)
|
c := cmd.(*btcjson.NodeCmd)
|
||||||
|
@ -3146,6 +3164,24 @@ func handleHelp(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (inter
|
||||||
return help, nil
|
return help, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleListBanned handles the listbanned command.
|
||||||
|
func handleListBanned(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
|
banned := s.cfg.ConnMgr.BannedPeers()
|
||||||
|
reply := make([]*btcjson.ListBannedResult, 0, len(banned))
|
||||||
|
for address, period := range banned {
|
||||||
|
since, until := period.since, period.until
|
||||||
|
r := btcjson.ListBannedResult{
|
||||||
|
Address: address,
|
||||||
|
BanCreated: since.Unix(),
|
||||||
|
BannedUntil: until.Unix(),
|
||||||
|
BanDuration: int64(until.Sub(since).Seconds()),
|
||||||
|
TimeRemaining: int64(time.Until(until).Seconds()),
|
||||||
|
}
|
||||||
|
reply = append(reply, &r)
|
||||||
|
}
|
||||||
|
return reply, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handlePing implements the ping command.
|
// handlePing implements the ping command.
|
||||||
func handlePing(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
func handlePing(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
// Ask server to ping \o_
|
// Ask server to ping \o_
|
||||||
|
@ -3749,6 +3785,59 @@ func handleSendRawTransaction(s *rpcServer, cmd interface{}, closeChan <-chan st
|
||||||
return tx.Hash().String(), nil
|
return tx.Hash().String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handleSetBan handles the setban command.
|
||||||
|
func handleSetBan(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
|
c := cmd.(*btcjson.SetBanCmd)
|
||||||
|
|
||||||
|
addr := net.ParseIP(c.Addr)
|
||||||
|
if addr == nil {
|
||||||
|
return nil, &btcjson.RPCError{
|
||||||
|
Code: btcjson.ErrRPCInvalidParameter,
|
||||||
|
Message: "invalid addr for setban",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
since := time.Now()
|
||||||
|
until := since.Add(time.Second * time.Duration(*c.BanTime))
|
||||||
|
if *c.BanTime == 0 {
|
||||||
|
until = since.Add(defaultBanDuration)
|
||||||
|
}
|
||||||
|
if *c.Absolute {
|
||||||
|
until = time.Unix(int64(*c.BanTime), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
switch c.SubCmd {
|
||||||
|
case "add":
|
||||||
|
err = s.cfg.ConnMgr.SetBan(addr.String(), since, until)
|
||||||
|
addr := addr.String()
|
||||||
|
peers := s.cfg.ConnMgr.ConnectedPeers()
|
||||||
|
for _, peer := range peers {
|
||||||
|
p := peer.ToPeer()
|
||||||
|
if p.NA().IP.String() == addr {
|
||||||
|
p.Disconnect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "remove":
|
||||||
|
err = s.cfg.ConnMgr.RemoveBan(addr.String())
|
||||||
|
default:
|
||||||
|
return nil, &btcjson.RPCError{
|
||||||
|
Code: btcjson.ErrRPCInvalidParameter,
|
||||||
|
Message: "invalid subcommand for setban",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, &btcjson.RPCError{
|
||||||
|
Code: btcjson.ErrRPCInvalidParameter,
|
||||||
|
Message: err.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no data returned unless an error.
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handleSetGenerate implements the setgenerate command.
|
// handleSetGenerate implements the setgenerate command.
|
||||||
func handleSetGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
func handleSetGenerate(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) (interface{}, error) {
|
||||||
c := cmd.(*btcjson.SetGenerateCmd)
|
c := cmd.(*btcjson.SetGenerateCmd)
|
||||||
|
@ -4806,6 +4895,18 @@ type rpcserverConnManager interface {
|
||||||
// ConnectedPeers returns an array consisting of all connected peers.
|
// ConnectedPeers returns an array consisting of all connected peers.
|
||||||
ConnectedPeers() []rpcserverPeer
|
ConnectedPeers() []rpcserverPeer
|
||||||
|
|
||||||
|
// BannedPeers returns an array consisting of all Banned peers.
|
||||||
|
BannedPeers() map[string]bannedPeriod
|
||||||
|
|
||||||
|
// SetBan add the addr to the ban list.
|
||||||
|
SetBan(addr string, since time.Time, until time.Time) error
|
||||||
|
|
||||||
|
// RemoveBan remove the subnet from the ban list.
|
||||||
|
RemoveBan(subnet string) error
|
||||||
|
|
||||||
|
// ClearBanned removes all banned IPs.
|
||||||
|
ClearBanned() error
|
||||||
|
|
||||||
// PersistentPeers returns an array consisting of all the persistent
|
// PersistentPeers returns an array consisting of all the persistent
|
||||||
// peers.
|
// peers.
|
||||||
PersistentPeers() []rpcserverPeer
|
PersistentPeers() []rpcserverPeer
|
||||||
|
|
|
@ -56,6 +56,9 @@ var helpDescsEnUS = map[string]string{
|
||||||
"createrawtransaction-locktime": "Locktime value; a non-zero value will also locktime-activate the inputs",
|
"createrawtransaction-locktime": "Locktime value; a non-zero value will also locktime-activate the inputs",
|
||||||
"createrawtransaction--result0": "Hex-encoded bytes of the serialized transaction",
|
"createrawtransaction--result0": "Hex-encoded bytes of the serialized transaction",
|
||||||
|
|
||||||
|
// ClearBannedCmd help.
|
||||||
|
"clearbanned--synopsis": "Clear all banned IPs.",
|
||||||
|
|
||||||
// ScriptSig help.
|
// ScriptSig help.
|
||||||
"scriptsig-asm": "Disassembly of the script",
|
"scriptsig-asm": "Disassembly of the script",
|
||||||
"scriptsig-hex": "Hex-encoded bytes of the script",
|
"scriptsig-hex": "Hex-encoded bytes of the script",
|
||||||
|
@ -636,6 +639,16 @@ var helpDescsEnUS = map[string]string{
|
||||||
"ping--synopsis": "Queues a ping to be sent to each connected peer.\n" +
|
"ping--synopsis": "Queues a ping to be sent to each connected peer.\n" +
|
||||||
"Ping times are provided by getpeerinfo via the pingtime and pingwait fields.",
|
"Ping times are provided by getpeerinfo via the pingtime and pingwait fields.",
|
||||||
|
|
||||||
|
// ListBannedCmd help.
|
||||||
|
"listbanned--synopsis": "List all banned IPs.",
|
||||||
|
|
||||||
|
// ListBannedResult help.
|
||||||
|
"listbannedresult-address": "The IP of the banned node.",
|
||||||
|
"listbannedresult-ban_created": "The UNIX epoch time the ban was created.",
|
||||||
|
"listbannedresult-banned_until": "The UNIX epoch time the ban expires.",
|
||||||
|
"listbannedresult-ban_duration": "The duration of the ban, in seconds.",
|
||||||
|
"listbannedresult-time_remaining": "The time remaining on the ban, in seconds",
|
||||||
|
|
||||||
// ReconsiderBlockCmd
|
// ReconsiderBlockCmd
|
||||||
"reconsiderblock--synopsis": "Reconsider a block for validation.",
|
"reconsiderblock--synopsis": "Reconsider a block for validation.",
|
||||||
"reconsiderblock-blockhash": "Hash of the block you want to reconsider",
|
"reconsiderblock-blockhash": "Hash of the block you want to reconsider",
|
||||||
|
@ -664,6 +677,13 @@ var helpDescsEnUS = map[string]string{
|
||||||
"sendrawtransaction--result0": "The hash of the transaction",
|
"sendrawtransaction--result0": "The hash of the transaction",
|
||||||
"allowhighfeesormaxfeerate-value": "Either the boolean value for the allowhighfees parameter in bitcoind < v0.19.0 or the numerical value for the maxfeerate field in bitcoind v0.19.0 and later",
|
"allowhighfeesormaxfeerate-value": "Either the boolean value for the allowhighfees parameter in bitcoind < v0.19.0 or the numerical value for the maxfeerate field in bitcoind v0.19.0 and later",
|
||||||
|
|
||||||
|
// SetBanCmd help.
|
||||||
|
"setban--synopsis": "Add or remove an IP from the banned list. (Currently, subnet is not supported.)",
|
||||||
|
"setban-addr": "The IP to ban. (Currently, subnet is not supported.)",
|
||||||
|
"setban-subcmd": "'add' to add an IP to the list, 'remove' to remove an IP from the list",
|
||||||
|
"setban-bantime": "Time in seconds the IP is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)",
|
||||||
|
"setban-absolute": "If set, the bantime must be an absolute timestamp expressed in UNIX epoch time; default to false.",
|
||||||
|
|
||||||
// SetGenerateCmd help.
|
// SetGenerateCmd help.
|
||||||
"setgenerate--synopsis": "Set the server to generate coins (mine) or not.",
|
"setgenerate--synopsis": "Set the server to generate coins (mine) or not.",
|
||||||
"setgenerate-generate": "Use true to enable generation, false to disable it",
|
"setgenerate-generate": "Use true to enable generation, false to disable it",
|
||||||
|
@ -880,6 +900,7 @@ var helpDescsEnUS = map[string]string{
|
||||||
// pointer to the type (or nil to indicate no return value).
|
// pointer to the type (or nil to indicate no return value).
|
||||||
var rpcResultTypes = map[string][]interface{}{
|
var rpcResultTypes = map[string][]interface{}{
|
||||||
"addnode": nil,
|
"addnode": nil,
|
||||||
|
"clearbanned": nil,
|
||||||
"createrawtransaction": {(*string)(nil)},
|
"createrawtransaction": {(*string)(nil)},
|
||||||
"debuglevel": {(*string)(nil), (*string)(nil)},
|
"debuglevel": {(*string)(nil), (*string)(nil)},
|
||||||
"decoderawtransaction": {(*btcjson.TxRawDecodeResult)(nil)},
|
"decoderawtransaction": {(*btcjson.TxRawDecodeResult)(nil)},
|
||||||
|
@ -892,11 +913,11 @@ var rpcResultTypes = map[string][]interface{}{
|
||||||
"getbestblock": {(*btcjson.GetBestBlockResult)(nil)},
|
"getbestblock": {(*btcjson.GetBestBlockResult)(nil)},
|
||||||
"getbestblockhash": {(*string)(nil)},
|
"getbestblockhash": {(*string)(nil)},
|
||||||
"getblock": {(*string)(nil), (*btcjson.GetBlockVerboseResult)(nil)},
|
"getblock": {(*string)(nil), (*btcjson.GetBlockVerboseResult)(nil)},
|
||||||
|
"getblockchaininfo": {(*btcjson.GetBlockChainInfoResult)(nil)},
|
||||||
"getblockcount": {(*int64)(nil)},
|
"getblockcount": {(*int64)(nil)},
|
||||||
"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)},
|
|
||||||
"getcfilter": {(*string)(nil)},
|
"getcfilter": {(*string)(nil)},
|
||||||
"getcfilterheader": {(*string)(nil)},
|
"getcfilterheader": {(*string)(nil)},
|
||||||
"getchaintips": {(*[]btcjson.GetChainTipsResult)(nil)},
|
"getchaintips": {(*[]btcjson.GetChainTipsResult)(nil)},
|
||||||
|
@ -918,13 +939,15 @@ var rpcResultTypes = map[string][]interface{}{
|
||||||
"getrawmempool": {(*[]string)(nil), (*btcjson.GetRawMempoolVerboseResult)(nil)},
|
"getrawmempool": {(*[]string)(nil), (*btcjson.GetRawMempoolVerboseResult)(nil)},
|
||||||
"getrawtransaction": {(*string)(nil), (*btcjson.TxRawResult)(nil)},
|
"getrawtransaction": {(*string)(nil), (*btcjson.TxRawResult)(nil)},
|
||||||
"gettxout": {(*btcjson.GetTxOutResult)(nil)},
|
"gettxout": {(*btcjson.GetTxOutResult)(nil)},
|
||||||
"node": nil,
|
|
||||||
"help": {(*string)(nil), (*string)(nil)},
|
"help": {(*string)(nil), (*string)(nil)},
|
||||||
"invalidateblock": nil,
|
"invalidateblock": nil,
|
||||||
|
"listbanned": {(*[]btcjson.ListBannedResult)(nil)},
|
||||||
|
"node": nil,
|
||||||
"ping": nil,
|
"ping": nil,
|
||||||
"reconsiderblock": nil,
|
"reconsiderblock": nil,
|
||||||
"searchrawtransactions": {(*string)(nil), (*[]btcjson.SearchRawTransactionsResult)(nil)},
|
"searchrawtransactions": {(*string)(nil), (*[]btcjson.SearchRawTransactionsResult)(nil)},
|
||||||
"sendrawtransaction": {(*string)(nil)},
|
"sendrawtransaction": {(*string)(nil)},
|
||||||
|
"setban": nil,
|
||||||
"setgenerate": nil,
|
"setgenerate": nil,
|
||||||
"signmessagewithprivkey": {(*string)(nil)},
|
"signmessagewithprivkey": {(*string)(nil)},
|
||||||
"stop": {(*string)(nil)},
|
"stop": {(*string)(nil)},
|
||||||
|
|
66
server.go
66
server.go
|
@ -156,13 +156,18 @@ type updatePeerHeightsMsg struct {
|
||||||
originPeer *peer.Peer
|
originPeer *peer.Peer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type bannedPeriod struct {
|
||||||
|
since time.Time
|
||||||
|
until time.Time
|
||||||
|
}
|
||||||
|
|
||||||
// peerState maintains state of inbound, persistent, outbound peers as well
|
// peerState maintains state of inbound, persistent, outbound peers as well
|
||||||
// as banned peers and outbound groups.
|
// as banned peers and outbound groups.
|
||||||
type peerState struct {
|
type peerState struct {
|
||||||
inboundPeers map[int32]*serverPeer
|
inboundPeers map[int32]*serverPeer
|
||||||
outboundPeers map[int32]*serverPeer
|
outboundPeers map[int32]*serverPeer
|
||||||
persistentPeers map[int32]*serverPeer
|
persistentPeers map[int32]*serverPeer
|
||||||
banned map[string]time.Time
|
banned map[string]bannedPeriod
|
||||||
outboundGroups map[string]int
|
outboundGroups map[string]int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1656,10 +1661,10 @@ func (s *server) handleAddPeerMsg(state *peerState, sp *serverPeer) bool {
|
||||||
sp.Disconnect()
|
sp.Disconnect()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if banEnd, ok := state.banned[host]; ok {
|
if ban, ok := state.banned[host]; ok {
|
||||||
if time.Now().Before(banEnd) {
|
if time.Now().Before(ban.until) {
|
||||||
srvrLog.Debugf("Peer %s is banned for another %v - disconnecting",
|
srvrLog.Infof("Peer %s is banned for another %v - disconnecting",
|
||||||
host, time.Until(banEnd))
|
host, time.Until(ban.until))
|
||||||
sp.Disconnect()
|
sp.Disconnect()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -1781,7 +1786,12 @@ func (s *server) handleBanPeerMsg(state *peerState, sp *serverPeer) {
|
||||||
direction := directionString(sp.Inbound())
|
direction := directionString(sp.Inbound())
|
||||||
srvrLog.Infof("Banned peer %s (%s) for %v", host, direction,
|
srvrLog.Infof("Banned peer %s (%s) for %v", host, direction,
|
||||||
cfg.BanDuration)
|
cfg.BanDuration)
|
||||||
state.banned[host] = time.Now().Add(cfg.BanDuration)
|
|
||||||
|
since := time.Now()
|
||||||
|
state.banned[host] = bannedPeriod{
|
||||||
|
since: since,
|
||||||
|
until: since.Add(cfg.BanDuration),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleRelayInvMsg deals with relaying inventory to peers that are not already
|
// handleRelayInvMsg deals with relaying inventory to peers that are not already
|
||||||
|
@ -1876,6 +1886,25 @@ type getPeersMsg struct {
|
||||||
reply chan []*serverPeer
|
reply chan []*serverPeer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type listBannedPeersMsg struct {
|
||||||
|
reply chan map[string]bannedPeriod
|
||||||
|
}
|
||||||
|
|
||||||
|
type setBanMsg struct {
|
||||||
|
addr string
|
||||||
|
since time.Time
|
||||||
|
until time.Time
|
||||||
|
reply chan error
|
||||||
|
}
|
||||||
|
|
||||||
|
type removeBanMsg struct {
|
||||||
|
addr string
|
||||||
|
reply chan error
|
||||||
|
}
|
||||||
|
|
||||||
|
type clearBannedMsg struct {
|
||||||
|
reply chan error
|
||||||
|
}
|
||||||
type getOutboundGroup struct {
|
type getOutboundGroup struct {
|
||||||
key string
|
key string
|
||||||
reply chan int
|
reply chan int
|
||||||
|
@ -1924,6 +1953,29 @@ func (s *server) handleQuery(state *peerState, querymsg interface{}) {
|
||||||
})
|
})
|
||||||
msg.reply <- peers
|
msg.reply <- peers
|
||||||
|
|
||||||
|
case listBannedPeersMsg:
|
||||||
|
banned := map[string]bannedPeriod{}
|
||||||
|
for host, ban := range state.banned {
|
||||||
|
banned[host] = ban
|
||||||
|
}
|
||||||
|
msg.reply <- banned
|
||||||
|
|
||||||
|
case setBanMsg:
|
||||||
|
ban := bannedPeriod{
|
||||||
|
since: msg.since,
|
||||||
|
until: msg.until,
|
||||||
|
}
|
||||||
|
state.banned[msg.addr] = ban
|
||||||
|
msg.reply <- nil
|
||||||
|
|
||||||
|
case removeBanMsg:
|
||||||
|
delete(state.banned, msg.addr)
|
||||||
|
msg.reply <- nil
|
||||||
|
|
||||||
|
case clearBannedMsg:
|
||||||
|
state.banned = map[string]bannedPeriod{}
|
||||||
|
msg.reply <- nil
|
||||||
|
|
||||||
case connectNodeMsg:
|
case connectNodeMsg:
|
||||||
// TODO: duplicate oneshots?
|
// TODO: duplicate oneshots?
|
||||||
// Limit max number of total peers.
|
// Limit max number of total peers.
|
||||||
|
@ -2161,7 +2213,7 @@ func (s *server) peerHandler() {
|
||||||
inboundPeers: make(map[int32]*serverPeer),
|
inboundPeers: make(map[int32]*serverPeer),
|
||||||
persistentPeers: make(map[int32]*serverPeer),
|
persistentPeers: make(map[int32]*serverPeer),
|
||||||
outboundPeers: make(map[int32]*serverPeer),
|
outboundPeers: make(map[int32]*serverPeer),
|
||||||
banned: make(map[string]time.Time),
|
banned: make(map[string]bannedPeriod),
|
||||||
outboundGroups: make(map[string]int),
|
outboundGroups: make(map[string]int),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue