diff --git a/blockchain/chain.go b/blockchain/chain.go index 810571adcb..f86470febf 100644 --- a/blockchain/chain.go +++ b/blockchain/chain.go @@ -818,25 +818,12 @@ func (b *BlockChain) connectBlock(node *blockNode, block, parent *dcrutil.Block, return err } - // Notify of spent and missed tickets. - b.sendNotification(NTSpentAndMissedTickets, - &TicketNotificationsData{ - Hash: node.hash, - Height: node.height, - StakeDifficulty: nextStakeDiff, - TicketsSpent: node.stakeNode.SpentByBlock(), - TicketsMissed: node.stakeNode.MissedByBlock(), - TicketsNew: nil, - }) - // Notify of new tickets. b.sendNotification(NTNewTickets, &TicketNotificationsData{ Hash: node.hash, Height: node.height, StakeDifficulty: nextStakeDiff, - TicketsSpent: nil, - TicketsMissed: nil, TicketsNew: node.stakeNode.NewTickets(), }) } diff --git a/blockchain/notifications.go b/blockchain/notifications.go index 47a9d9108b..622d5eb00f 100644 --- a/blockchain/notifications.go +++ b/blockchain/notifications.go @@ -66,10 +66,6 @@ const ( // place. NTReorganization - // NTSpentAndMissedTickets indicates spent or missed tickets from a newly - // accepted block. - NTSpentAndMissedTickets - // NTNewTickets indicates newly maturing tickets from a newly accepted // block. NTNewTickets @@ -78,15 +74,14 @@ const ( // notificationTypeStrings is a map of notification types back to their constant // names for pretty printing. var notificationTypeStrings = map[NotificationType]string{ - NTNewTipBlockChecked: "NTNewTipBlockChecked", - NTBlockAccepted: "NTBlockAccepted", - NTBlockConnected: "NTBlockConnected", - NTBlockDisconnected: "NTBlockDisconnected", - NTChainReorgStarted: "NTChainReorgStarted", - NTChainReorgDone: "NTChainReorgDone", - NTReorganization: "NTReorganization", - NTSpentAndMissedTickets: "NTSpentAndMissedTickets", - NTNewTickets: "NTNewTickets", + NTNewTipBlockChecked: "NTNewTipBlockChecked", + NTBlockAccepted: "NTBlockAccepted", + NTBlockConnected: "NTBlockConnected", + NTBlockDisconnected: "NTBlockDisconnected", + NTChainReorgStarted: "NTChainReorgStarted", + NTChainReorgDone: "NTChainReorgDone", + NTReorganization: "NTReorganization", + NTNewTickets: "NTNewTickets", } // String returns the NotificationType in human-readable form. @@ -166,14 +161,12 @@ type ReorganizationNtfnsData struct { NewHeight int64 } -// TicketNotificationsData is the structure for new/spent/missed ticket -// notifications at blockchain HEAD that are outgoing from chain. +// TicketNotificationsData is the structure for data indicating information +// about new tickets in a connected block. type TicketNotificationsData struct { Hash chainhash.Hash Height int64 StakeDifficulty int64 - TicketsSpent []chainhash.Hash - TicketsMissed []chainhash.Hash TicketsNew []chainhash.Hash } @@ -187,7 +180,6 @@ type TicketNotificationsData struct { // - NTChainReorgStarted: nil // - NTChainReorgDone: nil // - NTReorganization: *ReorganizationNtfnsData -// - NTSpentAndMissedTickets: *TicketNotificationsData // - NTNewTickets: *TicketNotificationsData type Notification struct { Type NotificationType diff --git a/blockchain/stakeext.go b/blockchain/stakeext.go index 07c41843a8..d3f939aea5 100644 --- a/blockchain/stakeext.go +++ b/blockchain/stakeext.go @@ -73,17 +73,6 @@ func (b *BlockChain) LiveTickets() ([]chainhash.Hash, error) { return sn.LiveTickets(), nil } -// MissedTickets returns all currently missed tickets from the stake database. -// -// This function is safe for concurrent access. -func (b *BlockChain) MissedTickets() ([]chainhash.Hash, error) { - b.chainLock.RLock() - sn := b.bestChain.Tip().stakeNode - b.chainLock.RUnlock() - - return sn.MissedTickets(), nil -} - // TicketsWithAddress returns a slice of ticket hashes that are currently live // corresponding to the given address. // @@ -142,51 +131,6 @@ func (b *BlockChain) CheckLiveTickets(hashes []chainhash.Hash) []bool { return existsSlice } -// CheckMissedTickets returns a slice of bools representing whether each ticket -// hash has been missed in the live ticket treap of the best node. -// -// This function is safe for concurrent access. -func (b *BlockChain) CheckMissedTickets(hashes []chainhash.Hash) []bool { - b.chainLock.RLock() - sn := b.bestChain.Tip().stakeNode - b.chainLock.RUnlock() - - existsSlice := make([]bool, len(hashes)) - for i := range hashes { - existsSlice[i] = sn.ExistsMissedTicket(hashes[i]) - } - - return existsSlice -} - -// CheckExpiredTicket returns whether or not a ticket was ever expired. -// -// This function is safe for concurrent access. -func (b *BlockChain) CheckExpiredTicket(hash chainhash.Hash) bool { - b.chainLock.RLock() - sn := b.bestChain.Tip().stakeNode - b.chainLock.RUnlock() - - return sn.ExistsExpiredTicket(hash) -} - -// CheckExpiredTickets returns whether or not a ticket in a slice of -// tickets was ever expired. -// -// This function is safe for concurrent access. -func (b *BlockChain) CheckExpiredTickets(hashes []chainhash.Hash) []bool { - b.chainLock.RLock() - sn := b.bestChain.Tip().stakeNode - b.chainLock.RUnlock() - - existsSlice := make([]bool, len(hashes)) - for i := range hashes { - existsSlice[i] = sn.ExistsExpiredTicket(hashes[i]) - } - - return existsSlice -} - // TicketPoolValue returns the current value of all the locked funds in the // ticket pool. // diff --git a/docs/json_rpc_api.mediawiki b/docs/json_rpc_api.mediawiki index 8c956bbec3..6157e57302 100644 --- a/docs/json_rpc_api.mediawiki +++ b/docs/json_rpc_api.mediawiki @@ -168,10 +168,6 @@ the method name for further details such as parameter and return information. |Y |Returns the existence of the provided addresses. |- -|[[#existsexpiredtickets|existsexpiredtickets]] -|Y -|Returns the existence of the provided tickets in the expired ticket map. -|- |[[#existsliveticket|existsliveticket]] |Y |Returns the existence of the provided ticket. @@ -184,10 +180,6 @@ the method name for further details such as parameter and return information. |Y |Returns the existence of the provided txs in the mempool. |- -|[[#existsmissedtickets|existsmissedtickets]] -|Y -|Returns the existence of the provided tickets in the missed ticket map. -|- |[[#generate|generate]] |N |When in simnet or regtest mode, generate a set number of blocks. @@ -352,10 +344,6 @@ the method name for further details such as parameter and return information. |Y |Returns live ticket hashes from the ticket database. |- -|[[#missedtickets|missedtickets]] -|Y -|Returns missed ticket hashes from the ticket database. -|- |[[#node|node]] |N |Attempts to add or remove a peer. @@ -823,28 +811,6 @@ the method name for further details such as parameter and return information. ---- -====existsexpiredtickets==== -{| -!Method -|existsexpiredtickets -|- -!Parameters -| -# txhashes: (json array, required) The array of tx hashes to check. -|- -!Description -|Returns the existence of the provided tickets in the expired ticket map. -|- -!Returns -|bitset Bitset of bools showing if tx hashes exist or not as expired tickets. -|- -!Example Return -|00 -|} - ----- - - ====existsliveticket==== {| !Method @@ -908,27 +874,6 @@ the method name for further details such as parameter and return information. ---- -====existsmissedtickets==== -{| -!Method -|existsmissedtickets -|- -!Parameters -| -# txhashes: (json array, required) The array of tx hashes to check. -|- -!Description -|Returns the existence of the provided tickets in the missed ticket map. -|- -!Returns -|bitset Bitset of bools showing if tx hashes exist or not as missed tickets. -|- -!Example Return -|00 -|} - ----- - ====generate==== {| !Method @@ -2223,27 +2168,6 @@ of the best block. ---- -====missedtickets==== -{| -!Method -|missedtickets -|- -!Parameters -|None -|- -!Description -| Returns missed ticket hashes from the ticket database. -|- -!Returns -|(json object) -: tickets: (json array) List of missed tickets. -|- -!Example Return -|{"tickets": ["f56cd8250ac399773bd0a5461587fd1512193476278c4e4b05efc3eca35ca3fe","071c140969f6d74b90e98df5713e07f83f246a92b4f13f365952b83e3922c6fe",...]} -|} - ----- - ====node==== {| !Method @@ -2712,10 +2636,6 @@ user. Click the method name for further details such as parameter and return in |Load, add to, or reload a websocket client's transaction filter for mempool transactions, new blocks and rescanblocks. |[[#relevanttxaccepted|relevanttxaccepted]] |- -|[[#rebroadcastmissed|rebroadcastmissed]] -|Asks the daemon to rebroadcast missed votes. -|[[#spentandmissedtickets|spentandmissedtickets]] -|- |[[#rebroadcastwinners|rebroadcastwinners]] |Asks the daemon to rebroadcast the winners of the voting lottery. |[[#winningtickets|winningtickets]] @@ -2736,10 +2656,6 @@ user. Click the method name for further details such as parameter and return in |Send notifications for all tickets that are chosen to vote. |[[#winningtickets|winningtickets]] |- -|[[#notifyspentandmissedtickets|notifyspentandmissedtickets]] -|Send notifications for all tickets that are spent or missed. -|[[#spentandmissedtickets|spentandmissedtickets]] -|- |[[#notifynewtickets|notifynewtickets]] |Send notifications for all new tickets that have matured. |[[#newtickets|newtickets]] @@ -3013,24 +2929,6 @@ NOTE: This is only required if an HTTP Authorization header is not being used. ---- -====rebroadcastmissed==== -{| -!Method -|rebroadcastmissed -|- -!Parameters -|None -|- -!Description -|Asks the daemon to rebroadcast missed votes via a [[#spentandmissedtickets|spentandmissedtickets]] notification. -|- -!Returns -|Nothing -|- -|} - ----- - ====rebroadcastwinners==== {| !Method @@ -3140,26 +3038,6 @@ NOTE: This is only required if an HTTP Authorization header is not being used. ---- -====notifyspentandmissedtickets==== -{| -!Method -|notifyspentandmissedtickets -|- -!Notifications -|[[#spentandmissedtickets|spentandmissedtickets]] -|- -!Parameters -|None -|- -!Description -|Send a spentandmissedtickets notification when tickets are spent or missed. -|- -!Returns -|Nothing -|} - ----- - ====notifynewtickets==== {| !Method @@ -3254,10 +3132,6 @@ The following is an overview of the JSON-RPC notifications used for Websocket co |Tickets were chosen to vote. |[[#notifywinningtickets|notifywinningtickets]] |- -|[[#spentandmissedtickets|spentandmissedtickets]] -|Tickets were spent or missed. -|[[#notifyspentandmissedtickets|notifyspentandmissedtickets]] -|- |[[#newtickets|newtickets]] |New tickets matured. |[[#notifynewtickets|notifynewtickets]] @@ -3504,30 +3378,6 @@ The redeemingtx notification for the same txout, after the spending transaction |} ---- -====spentandmissedtickets==== -{| -!Method -|spentandmissedtickets -|- -!Request -|[[#notifyspentandmissedtickets|notifyspentandmissedtickets]] -|- -!Parameters -| -# Hash: (string) the hash of the block. -# Height: (numeric) the height of the block. -# StakeDiff: (numeric) the stake difficulty of the block. -# Tickets: (object) the tickets that have been spent or missed. -|- -!Description -|Notifies a client when tickets have been spent or missed. -|- -!Example -|Example spentandmissedtickets notification for block 479903 on testnet: -: {"jsonrpc": "1.0", "method": "spentandmissedtickets", "params": ["00000044a6c0e2fb8f4feae2ac1133443859407abcf27d5d3a29d7d16eda8bc4", 479903, 9003800525, {"2911dbd36f0bf09e9e84d223b076413d34c39dea7a060c32e5271d0dbb64b332": "spent", "5edc39e2e5f2fccac6d3a10ae7b0cb51031472cc606d450bbf1d5680083f20a1": "spent", "67ec8b66c5bfc1277cc6c6fc00d1b9e9b1c4d61baed7774843ca86200876fe91": "spent", "c2ca81646dc7afb2165354bbe9fcbf8f3d1e97e4a8361934d43db8cdc7ffcdc0": "spent", "da5b300e1a05b9aad2323916cc4ec6eff98962fcb87787dbe24d25b8ea5b102c": "spent"}], "id": null} -|} ----- - ====newtickets==== {| !Method diff --git a/internal/rpcserver/interface.go b/internal/rpcserver/interface.go index c43055c631..40a2b19691 100644 --- a/internal/rpcserver/interface.go +++ b/internal/rpcserver/interface.go @@ -249,9 +249,6 @@ type Chain interface { // provided block hash. ChainWork(hash *chainhash.Hash) (*big.Int, error) - // CheckExpiredTicket returns whether or not a ticket was ever expired. - CheckExpiredTickets(hashes []chainhash.Hash) []bool - // CheckLiveTicket returns whether or not a ticket exists in the live ticket // treap of the best node. CheckLiveTicket(hash chainhash.Hash) bool @@ -260,10 +257,6 @@ type Chain interface { // exists in the live ticket treap of the best node. CheckLiveTickets(hashes []chainhash.Hash) []bool - // CheckMissedTickets returns a slice of bools representing whether each ticket - // hash has been missed in the live ticket treap of the best node. - CheckMissedTickets(hashes []chainhash.Hash) []bool - // CountVoteVersion returns the total number of version votes for the current // rule change activation interval. CountVoteVersion(version uint32) (uint32, error) @@ -359,9 +352,6 @@ type Chain interface { // or an error if it doesn't exist. MedianTimeByHash(hash *chainhash.Hash) (time.Time, error) - // MissedTickets returns all currently missed tickets. - MissedTickets() ([]chainhash.Hash, error) - // NextThresholdState returns the current rule change threshold state of the // given deployment ID for the block AFTER the provided block hash. NextThresholdState(hash *chainhash.Hash, version uint32, deploymentID string) (blockchain.ThresholdStateTuple, error) @@ -700,10 +690,6 @@ type NtfnManager interface { // processing. NotifyWinningTickets(wtnd *WinningTicketsNtfnData) - // NotifySpentAndMissedTickets passes ticket spend and missing data for an - // incoming block to the manager for processing. - NotifySpentAndMissedTickets(tnd *blockchain.TicketNotificationsData) - // NotifyNewTickets passes a new ticket data for an incoming block to the // manager for processing. NotifyNewTickets(tnd *blockchain.TicketNotificationsData) @@ -747,14 +733,6 @@ type NtfnManager interface { // the passed websocket client. UnregisterWinningTickets(wsc *wsClient) - // RegisterSpentAndMissedTickets requests spent/missed tickets update notifications - // to the passed websocket client. - RegisterSpentAndMissedTickets(wsc *wsClient) - - // UnregisterSpentAndMissedTickets removes spent/missed ticket notifications for - // the passed websocket client. - UnregisterSpentAndMissedTickets(wsc *wsClient) - // RegisterNewTickets requests spent/missed tickets update notifications // to the passed websocket client. RegisterNewTickets(wsc *wsClient) diff --git a/internal/rpcserver/rpcserver.go b/internal/rpcserver/rpcserver.go index aa2158da71..a10caa6377 100644 --- a/internal/rpcserver/rpcserver.go +++ b/internal/rpcserver/rpcserver.go @@ -59,7 +59,7 @@ import ( // API version constants const ( - jsonrpcSemverMajor = 7 + jsonrpcSemverMajor = 8 jsonrpcSemverMinor = 0 jsonrpcSemverPatch = 0 ) @@ -167,11 +167,9 @@ var rpcHandlersBeforeInit = map[types.Method]commandHandler{ "estimatestakediff": handleEstimateStakeDiff, "existsaddress": handleExistsAddress, "existsaddresses": handleExistsAddresses, - "existsexpiredtickets": handleExistsExpiredTickets, "existsliveticket": handleExistsLiveTicket, "existslivetickets": handleExistsLiveTickets, "existsmempooltxs": handleExistsMempoolTxs, - "existsmissedtickets": handleExistsMissedTickets, "generate": handleGenerate, "getaddednodeinfo": handleGetAddedNodeInfo, "getbestblock": handleGetBestBlock, @@ -213,7 +211,6 @@ var rpcHandlersBeforeInit = map[types.Method]commandHandler{ "help": handleHelp, "invalidateblock": handleInvalidateBlock, "livetickets": handleLiveTickets, - "missedtickets": handleMissedTickets, "node": handleNode, "ping": handlePing, "reconsiderblock": handleReconsiderBlock, @@ -331,7 +328,6 @@ var rpcLimited = map[string]struct{}{ "notifyspent": {}, "rescan": {}, "session": {}, - "rebroadcastmissed": {}, "rebroadcastwinners": {}, // Websockets AND HTTP/S commands @@ -348,11 +344,9 @@ var rpcLimited = map[string]struct{}{ "estimatestakediff": {}, "existsaddress": {}, "existsaddresses": {}, - "existsexpiredtickets": {}, "existsliveticket": {}, "existslivetickets": {}, "existsmempooltxs": {}, - "existsmissedtickets": {}, "getbestblock": {}, "getbestblockhash": {}, "getblock": {}, @@ -380,7 +374,6 @@ var rpcLimited = map[string]struct{}{ "gettxout": {}, "getvoteinfo": {}, "livetickets": {}, - "missedtickets": {}, "regentemplate": {}, "searchrawtransactions": {}, "sendrawtransaction": {}, @@ -1657,64 +1650,6 @@ func decodeHashPointers(strs []string) ([]*chainhash.Hash, error) { return hashes, nil } -// handleExistsMissedTickets implements the existsmissedtickets command. -// -// TODO: Add an upper bound to the number of hashes that can be checked. This -// will come with a major RPC version bump. -func handleExistsMissedTickets(_ context.Context, s *Server, cmd interface{}) (interface{}, error) { - c := cmd.(*types.ExistsMissedTicketsCmd) - - hashes, err := decodeHashes(c.TxHashes) - if err != nil { - return nil, err - } - - exists := s.cfg.Chain.CheckMissedTickets(hashes) - if len(exists) != len(hashes) { - return nil, rpcInvalidError("Invalid missed ticket count "+ - "got %v, want %v", len(exists), len(hashes)) - } - - // Convert the slice of bools into a compacted set of bit flags. - set := bitset.NewBytes(len(hashes)) - for i := range exists { - if exists[i] { - set.Set(i) - } - } - - return hex.EncodeToString([]byte(set)), nil -} - -// handleExistsExpiredTickets implements the existsexpiredtickets command. -// -// TODO: Add an upper bound to the number of hashes that can be checked. This -// will come with a major RPC version bump. -func handleExistsExpiredTickets(_ context.Context, s *Server, cmd interface{}) (interface{}, error) { - c := cmd.(*types.ExistsExpiredTicketsCmd) - - hashes, err := decodeHashes(c.TxHashes) - if err != nil { - return nil, err - } - - exists := s.cfg.Chain.CheckExpiredTickets(hashes) - if len(exists) != len(hashes) { - return nil, rpcInvalidError("Invalid expired ticket count "+ - "got %v, want %v", len(exists), len(hashes)) - } - - // Convert the slice of bools into a compacted set of bit flags. - set := bitset.NewBytes(len(hashes)) - for i := range exists { - if exists[i] { - set.Set(i) - } - } - - return hex.EncodeToString([]byte(set)), nil -} - // handleExistsLiveTicket implements the existsliveticket command. func handleExistsLiveTicket(_ context.Context, s *Server, cmd interface{}) (interface{}, error) { c := cmd.(*types.ExistsLiveTicketCmd) @@ -4059,22 +3994,6 @@ func handleLiveTickets(_ context.Context, s *Server, cmd interface{}) (interface return types.LiveTicketsResult{Tickets: ltString}, nil } -// handleMissedTickets implements the missedtickets command. -func handleMissedTickets(_ context.Context, s *Server, cmd interface{}) (interface{}, error) { - mt, err := s.cfg.Chain.MissedTickets() - if err != nil { - return nil, rpcInternalError("Could not get missed tickets "+ - err.Error(), "") - } - - mtString := make([]string, len(mt)) - for i, hash := range mt { - mtString[i] = hash.String() - } - - return types.MissedTicketsResult{Tickets: mtString}, nil -} - // handlePing implements the ping command. func handlePing(_ context.Context, s *Server, cmd interface{}) (interface{}, error) { // Ask server to ping \o_ @@ -5779,12 +5698,6 @@ func (s *Server) NotifyBlockConnected(block *dcrutil.Block) { s.ntfnMgr.NotifyBlockConnected(block) } -// NotifySpentAndMissedTickets notifies websocket clients that have registered -// for spent and missed ticket updates. -func (s *Server) NotifySpentAndMissedTickets(tnd *blockchain.TicketNotificationsData) { - s.ntfnMgr.NotifySpentAndMissedTickets(tnd) -} - // NotifyBlockDisconnected notifies websocket clients that have registered for // block updates when a block is disconnected from the main chain. func (s *Server) NotifyBlockDisconnected(block *dcrutil.Block) { diff --git a/internal/rpcserver/rpcserverhandlers_test.go b/internal/rpcserver/rpcserverhandlers_test.go index dbe3bd944d..eabe37e8ef 100644 --- a/internal/rpcserver/rpcserverhandlers_test.go +++ b/internal/rpcserver/rpcserverhandlers_test.go @@ -151,10 +151,8 @@ type testRPCChain struct { chainTips []blockchain.ChainTipInfo chainWork *big.Int chainWorkErr error - checkExpiredTickets []bool checkLiveTicket bool checkLiveTickets []bool - checkMissedTickets []bool countVoteVersion uint32 countVoteVersionErr error estimateNextStakeDifficultyFn func(hash *chainhash.Hash, newTickets int64, useMaxTickets bool) (diff int64, err error) @@ -252,12 +250,6 @@ func (c *testRPCChain) ChainWork(hash *chainhash.Hash) (*big.Int, error) { return c.chainWork, c.chainWorkErr } -// CheckExpiredTickets returns a mocked slice of bools representing -// whether each ticket hash has expired. -func (c *testRPCChain) CheckExpiredTickets(hashes []chainhash.Hash) []bool { - return c.checkExpiredTickets -} - // CheckLiveTicket returns a mocked result of whether or not a ticket // exists in the live ticket treap of the best node. func (c *testRPCChain) CheckLiveTicket(hash chainhash.Hash) bool { @@ -270,12 +262,6 @@ func (c *testRPCChain) CheckLiveTickets(hashes []chainhash.Hash) []bool { return c.checkLiveTickets } -// CheckMissedTickets returns a mocked slice of bools representing -// whether each ticket hash has been missed. -func (c *testRPCChain) CheckMissedTickets(hashes []chainhash.Hash) []bool { - return c.checkMissedTickets -} - // CountVoteVersion returns a mocked total number of version votes for the current // rule change activation interval. func (c *testRPCChain) CountVoteVersion(version uint32) (uint32, error) { @@ -1209,10 +1195,6 @@ func (mgr *testNtfnManager) NotifyReorganization(rd *blockchain.ReorganizationNt // processing. func (mgr *testNtfnManager) NotifyWinningTickets(wtnd *WinningTicketsNtfnData) {} -// NotifySpentAndMissedTickets passes ticket spend and missing data for an -// incoming block to the manager for processing. -func (mgr *testNtfnManager) NotifySpentAndMissedTickets(tnd *blockchain.TicketNotificationsData) {} - // NotifyNewTickets passes new ticket data for an incoming block to the // manager for processing. func (mgr *testNtfnManager) NotifyNewTickets(tnd *blockchain.TicketNotificationsData) {} @@ -1258,14 +1240,6 @@ func (mgr *testNtfnManager) RegisterWinningTickets(wsc *wsClient) {} // the passed websocket client. func (mgr *testNtfnManager) UnregisterWinningTickets(wsc *wsClient) {} -// RegisterSpentAndMissedTickets requests spent/missed tickets update notifications -// to the passed websocket client. -func (mgr *testNtfnManager) RegisterSpentAndMissedTickets(wsc *wsClient) {} - -// UnregisterSpentAndMissedTickets removes spent/missed ticket notifications for -// the passed websocket client. -func (mgr *testNtfnManager) UnregisterSpentAndMissedTickets(wsc *wsClient) {} - // RegisterNewTickets requests spent/missed tickets update notifications // to the passed websocket client. func (mgr *testNtfnManager) RegisterNewTickets(wsc *wsClient) {} @@ -3301,94 +3275,6 @@ func TestHandleExistsAddresses(t *testing.T) { }}) } -func TestHandleExistsExpiredTickets(t *testing.T) { - t.Parallel() - - defaultCmdTxHashes := []string{ - "1189cbe656c2ef1e0fcb91f107624d9aa8f0db7b28e6a86f694a4cf49abc5e39", - "2189cbe656c2ef1e0fcb91f107624d9aa8f0db7b28e6a86f694a4cf49abc5e39", - } - testRPCServerHandler(t, []rpcTest{{ - name: "handleExistsExpiredTickets: both tickets exist", - handler: handleExistsExpiredTickets, - cmd: &types.ExistsExpiredTicketsCmd{ - TxHashes: defaultCmdTxHashes, - }, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.checkExpiredTickets = []bool{true, true} - return chain - }(), - result: "03", - }, { - name: "handleExistsExpiredTickets: only first ticket exists", - handler: handleExistsExpiredTickets, - cmd: &types.ExistsExpiredTicketsCmd{ - TxHashes: defaultCmdTxHashes, - }, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.checkExpiredTickets = []bool{true, false} - return chain - }(), - result: "01", - }, { - name: "handleExistsExpiredTickets: only second ticket exists", - handler: handleExistsExpiredTickets, - cmd: &types.ExistsExpiredTicketsCmd{ - TxHashes: defaultCmdTxHashes, - }, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.checkExpiredTickets = []bool{false, true} - return chain - }(), - result: "02", - }, { - name: "handleExistsExpiredTickets: none of the tickets exist", - handler: handleExistsExpiredTickets, - cmd: &types.ExistsExpiredTicketsCmd{ - TxHashes: defaultCmdTxHashes, - }, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.checkExpiredTickets = []bool{false, false} - return chain - }(), - result: "00", - }, { - name: "handleExistsExpiredTickets: invalid hash", - handler: handleExistsExpiredTickets, - cmd: &types.ExistsExpiredTicketsCmd{ - TxHashes: []string{ - "g189cbe656c2ef1e0fcb91f107624d9aa8f0db7b28e6a86f694a4cf49abc5e39", - }, - }, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.checkExpiredTickets = []bool{true, true} - return chain - }(), - wantErr: true, - errCode: dcrjson.ErrRPCDecodeHexString, - }, { - name: "handleExistsExpiredTickets: invalid missed ticket count", - handler: handleExistsExpiredTickets, - cmd: &types.ExistsExpiredTicketsCmd{ - TxHashes: []string{ - "1189cbe656c2ef1e0fcb91f107624d9aa8f0db7b28e6a86f694a4cf49abc5e39", - }, - }, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.checkExpiredTickets = []bool{true, true} - return chain - }(), - wantErr: true, - errCode: dcrjson.ErrRPCInvalidParameter, - }}) -} - func TestHandleExistsLiveTicket(t *testing.T) { t.Parallel() @@ -3550,89 +3436,6 @@ func TestHandleExistsMempoolTxs(t *testing.T) { }}) } -func TestHandleExistsMissedTickets(t *testing.T) { - t.Parallel() - - defaultCmdTxHashes := []string{ - "1189cbe656c2ef1e0fcb91f107624d9aa8f0db7b28e6a86f694a4cf49abc5e39", - "2189cbe656c2ef1e0fcb91f107624d9aa8f0db7b28e6a86f694a4cf49abc5e39", - } - testRPCServerHandler(t, []rpcTest{{ - name: "handleExistsMissedTickets: both tickets exist", - handler: handleExistsMissedTickets, - cmd: &types.ExistsMissedTicketsCmd{ - TxHashes: defaultCmdTxHashes, - }, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.checkMissedTickets = []bool{true, true} - return chain - }(), - result: "03", - }, { - name: "handleExistsMissedTickets: only first ticket exists", - handler: handleExistsMissedTickets, - cmd: &types.ExistsMissedTicketsCmd{ - TxHashes: defaultCmdTxHashes, - }, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.checkMissedTickets = []bool{true, false} - return chain - }(), - result: "01", - }, { - name: "handleExistsMissedTickets: only second ticket exists", - handler: handleExistsMissedTickets, - cmd: &types.ExistsMissedTicketsCmd{ - TxHashes: defaultCmdTxHashes, - }, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.checkMissedTickets = []bool{false, true} - return chain - }(), - result: "02", - }, { - name: "handleExistsMissedTickets: none of the tickets exist", - handler: handleExistsMissedTickets, - cmd: &types.ExistsMissedTicketsCmd{ - TxHashes: defaultCmdTxHashes, - }, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.checkMissedTickets = []bool{false, false} - return chain - }(), - result: "00", - }, { - name: "handleExistsMissedTickets: invalid hash", - handler: handleExistsMissedTickets, - cmd: &types.ExistsMissedTicketsCmd{ - TxHashes: []string{ - "g189cbe656c2ef1e0fcb91f107624d9aa8f0db7b28e6a86f694a4cf49abc5e39", - }, - }, - wantErr: true, - errCode: dcrjson.ErrRPCDecodeHexString, - }, { - name: "handleExistsMissedTickets: invalid missed ticket count", - handler: handleExistsMissedTickets, - cmd: &types.ExistsMissedTicketsCmd{ - TxHashes: []string{ - "1189cbe656c2ef1e0fcb91f107624d9aa8f0db7b28e6a86f694a4cf49abc5e39", - }, - }, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.checkMissedTickets = []bool{true, true} - return chain - }(), - wantErr: true, - errCode: dcrjson.ErrRPCInvalidParameter, - }}) -} - func TestHandleGenerate(t *testing.T) { t.Parallel() @@ -5521,45 +5324,6 @@ func TestHandleLiveTickets(t *testing.T) { }}) } -func TestHandleMissedTickets(t *testing.T) { - t.Parallel() - - tkt1 := mustParseHash("1f6631957b4060d81ba7e760ec9c8150ba028eb051ddadf2b9749a5ccda1a955") - tkt2 := mustParseHash("eca7e802590df60f7d300b6170f63dfab213b26421ed2e70de3ec2224cb9e460") - - testRPCServerHandler(t, []rpcTest{{ - name: "handleMissedTickets: no missed tickets", - handler: handleMissedTickets, - cmd: &types.MissedTicketsCmd{}, - result: types.MissedTicketsResult{ - Tickets: []string{}, - }, - }, { - name: "handleMissedTickets: two missed tickets", - handler: handleMissedTickets, - cmd: &types.MissedTicketsCmd{}, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.missedTickets = []chainhash.Hash{*tkt1, *tkt2} - return chain - }(), - result: types.MissedTicketsResult{ - Tickets: []string{tkt1.String(), tkt2.String()}, - }, - }, { - name: "handleMissedTickets: unable to fetch missed tickets", - handler: handleMissedTickets, - cmd: &types.MissedTicketsCmd{}, - mockChain: func() *testRPCChain { - chain := defaultMockRPCChain() - chain.missedTicketsErr = errors.New("unable to fetch missed tickets") - return chain - }(), - wantErr: true, - errCode: dcrjson.ErrRPCInternal.Code, - }}) -} - func TestHandleNode(t *testing.T) { t.Parallel() diff --git a/internal/rpcserver/rpcserverhelp.go b/internal/rpcserver/rpcserverhelp.go index e9e78ffdc4..4c7993ff25 100644 --- a/internal/rpcserver/rpcserverhelp.go +++ b/internal/rpcserver/rpcserverhelp.go @@ -174,16 +174,6 @@ var helpDescsEnUS = map[string]string{ "existsaddresses-addresses": "The addresses to check", "existsaddresses--result0": "Bitset of bools showing if addresses exist or not", - // ExitsMissedTicketsCmd help. - "existsmissedtickets--synopsis": "Test for the existence of the provided tickets in the missed ticket map", - "existsmissedtickets-txhashes": "Array of hashes to check", - "existsmissedtickets--result0": "Bool blob showing if the ticket exists in the missed ticket database or not", - - // ExistsExpiredTicketsCmd help. - "existsexpiredtickets--synopsis": "Test for the existence of the provided tickets in the expired ticket map", - "existsexpiredtickets-txhashes": "Array of hashes to check", - "existsexpiredtickets--result0": "Bool blob showing if ticket exists in the expired ticket database or not", - // ExistsLiveTicketCmd help. "existsliveticket--synopsis": "Test for the existence of the provided ticket", "existsliveticket-txhash": "The ticket hash to check", @@ -735,9 +725,6 @@ var helpDescsEnUS = map[string]string{ "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.", - // RebroadcastMissed help. - "rebroadcastmissed--synopsis": "Asks the daemon to rebroadcast missed votes.", - // RebroadcastWinnersCmd help. "rebroadcastwinners--synopsis": "Asks the daemon to rebroadcast the winners of the voting lottery.", @@ -820,9 +807,6 @@ var helpDescsEnUS = map[string]string{ "session--synopsis": "Return details regarding a websocket client's current connection session.", "sessionresult-sessionid": "The unique session ID for a client's websocket connection.", - // NotifySpentAndMissedTicketsCmd help - "notifyspentandmissedtickets--synopsis": "Request notifications for whenever tickets are spent or missed.", - // NotifyNewTicketsCmd help "notifynewtickets--synopsis": "Request notifications for whenever new tickets are found.", @@ -900,10 +884,6 @@ var helpDescsEnUS = map[string]string{ "livetickets--synopsis": "Returns live ticket hashes from the ticket database", "liveticketsresult-tickets": "List of live tickets", - // MissedTickets help. - "missedtickets--synopsis": "Returns missed ticket hashes from the ticket database", - "missedticketsresult-tickets": "List of missed tickets", - // TicketBuckets help. "ticketbuckets--synopsis": "Request for the number of tickets currently in each bucket of the ticket database.", "ticketbucket-tickets": "Number of tickets in bucket.", @@ -1001,8 +981,6 @@ var rpcResultTypes = map[types.Method][]interface{}{ "estimatestakediff": {(*types.EstimateStakeDiffResult)(nil)}, "existsaddress": {(*bool)(nil)}, "existsaddresses": {(*string)(nil)}, - "existsmissedtickets": {(*string)(nil)}, - "existsexpiredtickets": {(*string)(nil)}, "existsliveticket": {(*bool)(nil)}, "existslivetickets": {(*string)(nil)}, "existsmempooltxs": {(*string)(nil)}, @@ -1047,7 +1025,6 @@ var rpcResultTypes = map[types.Method][]interface{}{ "help": {(*string)(nil), (*string)(nil)}, "invalidateblock": nil, "livetickets": {(*types.LiveTicketsResult)(nil)}, - "missedtickets": {(*types.MissedTicketsResult)(nil)}, "node": nil, "ping": nil, "reconsiderblock": nil, @@ -1067,26 +1044,24 @@ var rpcResultTypes = map[types.Method][]interface{}{ "version": {(*map[string]types.VersionResult)(nil)}, // Websocket commands. - "loadtxfilter": nil, - "notifywinningtickets": nil, - "notifyspentandmissedtickets": nil, - "notifynewtickets": nil, - "notifyblocks": nil, - "notifywork": nil, - "notifytspend": nil, - "notifynewtransactions": nil, - "notifyreceived": nil, - "notifyspent": nil, - "rebroadcastmissed": nil, - "rebroadcastwinners": nil, - "rescan": nil, - "session": {(*types.SessionResult)(nil)}, - "stopnotifyblocks": nil, - "stopnotifywork": nil, - "stopnotifytspend": nil, - "stopnotifynewtransactions": nil, - "stopnotifyreceived": nil, - "stopnotifyspent": nil, + "loadtxfilter": nil, + "notifywinningtickets": nil, + "notifynewtickets": nil, + "notifyblocks": nil, + "notifywork": nil, + "notifytspend": nil, + "notifynewtransactions": nil, + "notifyreceived": nil, + "notifyspent": nil, + "rebroadcastwinners": nil, + "rescan": nil, + "session": {(*types.SessionResult)(nil)}, + "stopnotifyblocks": nil, + "stopnotifywork": nil, + "stopnotifytspend": nil, + "stopnotifynewtransactions": nil, + "stopnotifyreceived": nil, + "stopnotifyspent": nil, } // helpCacher provides a concurrent safe type that provides help and usage for diff --git a/internal/rpcserver/rpcwebsocket.go b/internal/rpcserver/rpcwebsocket.go index b16d5d6e89..07b30dac44 100644 --- a/internal/rpcserver/rpcwebsocket.go +++ b/internal/rpcserver/rpcwebsocket.go @@ -77,23 +77,21 @@ type wsCommandHandler func(*wsClient, interface{}) (interface{}, error) // causes a dependency loop. var wsHandlers map[types.Method]wsCommandHandler var wsHandlersBeforeInit = map[types.Method]wsCommandHandler{ - "help": handleWebsocketHelp, - "loadtxfilter": handleLoadTxFilter, - "notifyblocks": handleNotifyBlocks, - "notifywork": handleNotifyWork, - "notifytspend": handleNotifyTSpend, - "notifywinningtickets": handleWinningTickets, - "notifyspentandmissedtickets": handleSpentAndMissedTickets, - "notifynewtickets": handleNewTickets, - "notifynewtransactions": handleNotifyNewTransactions, - "rebroadcastmissed": handleRebroadcastMissed, - "rebroadcastwinners": handleRebroadcastWinners, - "rescan": handleRescan, - "session": handleSession, - "stopnotifyblocks": handleStopNotifyBlocks, - "stopnotifywork": handleStopNotifyWork, - "stopnotifytspend": handleStopNotifyTSpend, - "stopnotifynewtransactions": handleStopNotifyNewTransactions, + "help": handleWebsocketHelp, + "loadtxfilter": handleLoadTxFilter, + "notifyblocks": handleNotifyBlocks, + "notifywork": handleNotifyWork, + "notifytspend": handleNotifyTSpend, + "notifywinningtickets": handleWinningTickets, + "notifynewtickets": handleNewTickets, + "notifynewtransactions": handleNotifyNewTransactions, + "rebroadcastwinners": handleRebroadcastWinners, + "rescan": handleRescan, + "session": handleSession, + "stopnotifyblocks": handleStopNotifyBlocks, + "stopnotifywork": handleStopNotifyWork, + "stopnotifytspend": handleStopNotifyTSpend, + "stopnotifynewtransactions": handleStopNotifyNewTransactions, } // WebsocketHandler handles a new websocket client by creating a new wsClient, @@ -258,16 +256,6 @@ func (m *wsNotificationManager) NotifyWinningTickets(wtnd *WinningTicketsNtfnDat } } -// NotifySpentAndMissedTickets passes ticket spend and missing data for an -// incoming block from the best chain to the notification manager for block -// notification processing. -func (m *wsNotificationManager) NotifySpentAndMissedTickets(tnd *blockchain.TicketNotificationsData) { - select { - case m.queueNotification <- (*notificationSpentAndMissedTickets)(tnd): - case <-m.quit: - } -} - // NotifyNewTickets passes a new ticket data for an incoming block from the best // chain to the notification manager for block notification processing. func (m *wsNotificationManager) NotifyNewTickets(tnd *blockchain.TicketNotificationsData) { @@ -418,7 +406,6 @@ type notificationWork mining.TemplateNtfn type notificationTSpend dcrutil.Tx type notificationReorganization blockchain.ReorganizationNtfnsData type notificationWinningTickets WinningTicketsNtfnData -type notificationSpentAndMissedTickets blockchain.TicketNotificationsData type notificationNewTickets blockchain.TicketNotificationsData type notificationTxAcceptedByMempool struct { isNew bool @@ -436,8 +423,6 @@ type notificationRegisterTSpend wsClient type notificationUnregisterTSpend wsClient type notificationRegisterWinningTickets wsClient type notificationUnregisterWinningTickets wsClient -type notificationRegisterSpentAndMissedTickets wsClient -type notificationUnregisterSpentAndMissedTickets wsClient type notificationRegisterNewTickets wsClient type notificationUnregisterNewTickets wsClient type notificationRegisterNewMempoolTxs wsClient @@ -460,7 +445,6 @@ func (m *wsNotificationManager) notificationHandler(ctx context.Context) { workNotifications := make(map[chan struct{}]*wsClient) tspendNotifications := make(map[chan struct{}]*wsClient) winningTicketNotifications := make(map[chan struct{}]*wsClient) - ticketSMNotifications := make(map[chan struct{}]*wsClient) ticketNewNotifications := make(map[chan struct{}]*wsClient) txNotifications := make(map[chan struct{}]*wsClient) @@ -506,10 +490,6 @@ out: m.notifyWinningTickets(winningTicketNotifications, (*WinningTicketsNtfnData)(n)) - case *notificationSpentAndMissedTickets: - m.notifySpentAndMissedTickets(ticketSMNotifications, - (*blockchain.TicketNotificationsData)(n)) - case *notificationNewTickets: m.notifyNewTickets(ticketNewNotifications, (*blockchain.TicketNotificationsData)(n)) @@ -552,14 +532,6 @@ out: wsc := (*wsClient)(n) delete(winningTicketNotifications, wsc.quit) - case *notificationRegisterSpentAndMissedTickets: - wsc := (*wsClient)(n) - ticketSMNotifications[wsc.quit] = wsc - - case *notificationUnregisterSpentAndMissedTickets: - wsc := (*wsClient)(n) - delete(ticketSMNotifications, wsc.quit) - case *notificationRegisterNewTickets: wsc := (*wsClient)(n) ticketNewNotifications[wsc.quit] = wsc @@ -581,7 +553,6 @@ out: delete(tspendNotifications, wsc.quit) delete(txNotifications, wsc.quit) delete(winningTicketNotifications, wsc.quit) - delete(ticketSMNotifications, wsc.quit) delete(ticketNewNotifications, wsc.quit) delete(clients, wsc.quit) @@ -1010,46 +981,6 @@ func (*wsNotificationManager) notifyWinningTickets( } } -// RegisterSpentAndMissedTickets requests spent/missed tickets update notifications -// to the passed websocket client. -func (m *wsNotificationManager) RegisterSpentAndMissedTickets(wsc *wsClient) { - m.queueNotification <- (*notificationRegisterSpentAndMissedTickets)(wsc) -} - -// UnregisterSpentAndMissedTickets removes spent/missed ticket notifications for -// the passed websocket client. -func (m *wsNotificationManager) UnregisterSpentAndMissedTickets(wsc *wsClient) { - m.queueNotification <- (*notificationUnregisterSpentAndMissedTickets)(wsc) -} - -// notifySpentAndMissedTickets notifies websocket clients that have registered for -// spent and missed ticket updates. -func (*wsNotificationManager) notifySpentAndMissedTickets(clients map[chan struct{}]*wsClient, tnd *blockchain.TicketNotificationsData) { - // Create a ticket map to export as JSON. - ticketMap := make(map[string]string) - for _, ticket := range tnd.TicketsMissed { - ticketMap[ticket.String()] = "missed" - } - for _, ticket := range tnd.TicketsSpent { - ticketMap[ticket.String()] = "spent" - } - - // Notify interested websocket clients about the connected block. - ntfn := types.NewSpentAndMissedTicketsNtfn(tnd.Hash.String(), - int32(tnd.Height), tnd.StakeDifficulty, ticketMap) - - marshalledJSON, err := dcrjson.MarshalCmd("1.0", nil, ntfn) - if err != nil { - log.Errorf("Failed to marshal spent and missed tickets "+ - "notification: %v", err) - return - } - - for _, wsc := range clients { - wsc.QueueNotification(marshalledJSON) - } -} - // RegisterNewTickets requests spent/missed tickets update notifications // to the passed websocket client. func (m *wsNotificationManager) RegisterNewTickets(wsc *wsClient) { @@ -2137,30 +2068,6 @@ func handleNotifyBlocks(wsc *wsClient, icmd interface{}) (interface{}, error) { return nil, nil } -// handleRebroadcastMissed implements the rebroadcastmissed command. -func handleRebroadcastMissed(wsc *wsClient, icmd interface{}) (interface{}, error) { - cfg := wsc.rpcServer.cfg - best := cfg.Chain.BestSnapshot() - mt, err := cfg.Chain.MissedTickets() - if err != nil { - return nil, rpcInternalError("Could not get missed tickets "+ - err.Error(), "") - } - - missedTicketsNtfn := &blockchain.TicketNotificationsData{ - Hash: best.Hash, - Height: best.Height, - StakeDifficulty: best.NextStakeDiff, - TicketsSpent: []chainhash.Hash{}, - TicketsMissed: mt, - TicketsNew: []chainhash.Hash{}, - } - - wsc.rpcServer.ntfnMgr.NotifySpentAndMissedTickets(missedTicketsNtfn) - - return nil, nil -} - // handleRebroadcastWinners implements the rebroadcastwinners command. func handleRebroadcastWinners(wsc *wsClient, icmd interface{}) (interface{}, error) { cfg := wsc.rpcServer.cfg @@ -2216,13 +2123,6 @@ func handleWinningTickets(wsc *wsClient, icmd interface{}) (interface{}, error) return nil, nil } -// handleSpentAndMissedTickets implements the notifyspentandmissedtickets command -// extension for websocket connections. -func handleSpentAndMissedTickets(wsc *wsClient, icmd interface{}) (interface{}, error) { - wsc.rpcServer.ntfnMgr.RegisterSpentAndMissedTickets(wsc) - return nil, nil -} - // handleNewTickets implements the notifynewtickets command extension for // websocket connections. func handleNewTickets(wsc *wsClient, icmd interface{}) (interface{}, error) { diff --git a/rpc/jsonrpc/types/chainsvrcmds.go b/rpc/jsonrpc/types/chainsvrcmds.go index 9b7e8bd5e2..3620fee48e 100644 --- a/rpc/jsonrpc/types/chainsvrcmds.go +++ b/rpc/jsonrpc/types/chainsvrcmds.go @@ -265,32 +265,6 @@ func NewExistsAddressesCmd(addresses []string) *ExistsAddressesCmd { } } -// ExistsMissedTicketsCmd defines the existsmissedtickets JSON-RPC command. -type ExistsMissedTicketsCmd struct { - TxHashes []string -} - -// NewExistsMissedTicketsCmd returns a new instance which can be used to issue an -// existsmissedtickets JSON-RPC command. -func NewExistsMissedTicketsCmd(txHashes []string) *ExistsMissedTicketsCmd { - return &ExistsMissedTicketsCmd{ - TxHashes: txHashes, - } -} - -// ExistsExpiredTicketsCmd defines the existsexpiredtickets JSON-RPC command. -type ExistsExpiredTicketsCmd struct { - TxHashes []string -} - -// NewExistsExpiredTicketsCmd returns a new instance which can be used to issue an -// existsexpiredtickets JSON-RPC command. -func NewExistsExpiredTicketsCmd(txHashes []string) *ExistsExpiredTicketsCmd { - return &ExistsExpiredTicketsCmd{ - TxHashes: txHashes, - } -} - // ExistsLiveTicketCmd defines the existsliveticket JSON-RPC command. type ExistsLiveTicketCmd struct { TxHash string @@ -882,16 +856,6 @@ func NewLiveTicketsCmd() *LiveTicketsCmd { return &LiveTicketsCmd{} } -// MissedTicketsCmd is a type handling custom marshaling and -// unmarshaling of missedtickets JSON RPC commands. -type MissedTicketsCmd struct{} - -// NewMissedTicketsCmd returns a new instance which can be used to issue a JSON-RPC -// missedtickets command. -func NewMissedTicketsCmd() *MissedTicketsCmd { - return &MissedTicketsCmd{} -} - // NodeCmd defines the dropnode JSON-RPC command. type NodeCmd struct { SubCmd NodeSubCmd `jsonrpcusage:"\"connect|remove|disconnect\""` @@ -1161,8 +1125,6 @@ func init() { dcrjson.MustRegister(Method("estimatestakediff"), (*EstimateStakeDiffCmd)(nil), flags) dcrjson.MustRegister(Method("existsaddress"), (*ExistsAddressCmd)(nil), flags) dcrjson.MustRegister(Method("existsaddresses"), (*ExistsAddressesCmd)(nil), flags) - dcrjson.MustRegister(Method("existsmissedtickets"), (*ExistsMissedTicketsCmd)(nil), flags) - dcrjson.MustRegister(Method("existsexpiredtickets"), (*ExistsExpiredTicketsCmd)(nil), flags) dcrjson.MustRegister(Method("existsliveticket"), (*ExistsLiveTicketCmd)(nil), flags) dcrjson.MustRegister(Method("existslivetickets"), (*ExistsLiveTicketsCmd)(nil), flags) dcrjson.MustRegister(Method("existsmempooltxs"), (*ExistsMempoolTxsCmd)(nil), flags) @@ -1207,7 +1169,6 @@ func init() { dcrjson.MustRegister(Method("help"), (*HelpCmd)(nil), flags) dcrjson.MustRegister(Method("invalidateblock"), (*InvalidateBlockCmd)(nil), flags) dcrjson.MustRegister(Method("livetickets"), (*LiveTicketsCmd)(nil), flags) - dcrjson.MustRegister(Method("missedtickets"), (*MissedTicketsCmd)(nil), flags) dcrjson.MustRegister(Method("node"), (*NodeCmd)(nil), flags) dcrjson.MustRegister(Method("ping"), (*PingCmd)(nil), flags) dcrjson.MustRegister(Method("reconsiderblock"), (*ReconsiderBlockCmd)(nil), flags) diff --git a/rpc/jsonrpc/types/chainsvrresults.go b/rpc/jsonrpc/types/chainsvrresults.go index 76b67d22e1..69f6c17854 100644 --- a/rpc/jsonrpc/types/chainsvrresults.go +++ b/rpc/jsonrpc/types/chainsvrresults.go @@ -466,12 +466,6 @@ type LiveTicketsResult struct { Tickets []string `json:"tickets"` } -// MissedTicketsResult models the data returned from the missedtickets -// command. -type MissedTicketsResult struct { - Tickets []string `json:"tickets"` -} - // FeeInfoBlock is ticket fee information about a block. type FeeInfoBlock struct { Height uint32 `json:"height"` diff --git a/rpc/jsonrpc/types/chainsvrwscmds.go b/rpc/jsonrpc/types/chainsvrwscmds.go index 967385532f..30d3045e0b 100644 --- a/rpc/jsonrpc/types/chainsvrwscmds.go +++ b/rpc/jsonrpc/types/chainsvrwscmds.go @@ -89,17 +89,6 @@ func NewNotifyWinningTicketsCmd() *NotifyWinningTicketsCmd { return &NotifyWinningTicketsCmd{} } -// NotifySpentAndMissedTicketsCmd is a type handling custom marshaling and -// unmarshaling of notifyspentandmissedtickets JSON websocket extension -// commands. -type NotifySpentAndMissedTicketsCmd struct { -} - -// NewNotifySpentAndMissedTicketsCmd creates a new NotifySpentAndMissedTicketsCmd. -func NewNotifySpentAndMissedTicketsCmd() *NotifySpentAndMissedTicketsCmd { - return &NotifySpentAndMissedTicketsCmd{} -} - // NotifyNewTicketsCmd is a type handling custom marshaling and // unmarshaling of notifynewtickets JSON websocket extension // commands. @@ -111,16 +100,6 @@ func NewNotifyNewTicketsCmd() *NotifyNewTicketsCmd { return &NotifyNewTicketsCmd{} } -// RebroadcastMissedCmd is a type handling custom marshaling and -// unmarshaling of rebroadcastmissed JSON RPC commands. -type RebroadcastMissedCmd struct{} - -// NewRebroadcastMissedCmd returns a new instance which can be used to -// issue a JSON-RPC rebroadcastmissed command. -func NewRebroadcastMissedCmd() *RebroadcastMissedCmd { - return &RebroadcastMissedCmd{} -} - // RebroadcastWinnersCmd is a type handling custom marshaling and // unmarshaling of rebroadcastwinners JSON RPC commands. type RebroadcastWinnersCmd struct{} @@ -217,9 +196,7 @@ func init() { dcrjson.MustRegister(Method("notifytspend"), (*NotifyTSpendCmd)(nil), flags) dcrjson.MustRegister(Method("notifynewtransactions"), (*NotifyNewTransactionsCmd)(nil), flags) dcrjson.MustRegister(Method("notifynewtickets"), (*NotifyNewTicketsCmd)(nil), flags) - dcrjson.MustRegister(Method("notifyspentandmissedtickets"), (*NotifySpentAndMissedTicketsCmd)(nil), flags) dcrjson.MustRegister(Method("notifywinningtickets"), (*NotifyWinningTicketsCmd)(nil), flags) - dcrjson.MustRegister(Method("rebroadcastmissed"), (*RebroadcastMissedCmd)(nil), flags) dcrjson.MustRegister(Method("rebroadcastwinners"), (*RebroadcastWinnersCmd)(nil), flags) dcrjson.MustRegister(Method("session"), (*SessionCmd)(nil), flags) dcrjson.MustRegister(Method("stopnotifyblocks"), (*StopNotifyBlocksCmd)(nil), flags) diff --git a/rpc/jsonrpc/types/chainsvrwscmds_test.go b/rpc/jsonrpc/types/chainsvrwscmds_test.go index 6aea93f4ac..cf1fd8fdaa 100644 --- a/rpc/jsonrpc/types/chainsvrwscmds_test.go +++ b/rpc/jsonrpc/types/chainsvrwscmds_test.go @@ -52,17 +52,6 @@ func TestChainSvrWsCmds(t *testing.T) { marshalled: `{"jsonrpc":"1.0","method":"notifywinningtickets","params":[],"id":1}`, unmarshalled: &NotifyWinningTicketsCmd{}, }, - { - name: "notifyspentandmissedtickets", - newCmd: func() (interface{}, error) { - return dcrjson.NewCmd(Method("notifyspentandmissedtickets")) - }, - staticCmd: func() interface{} { - return NewNotifySpentAndMissedTicketsCmd() - }, - marshalled: `{"jsonrpc":"1.0","method":"notifyspentandmissedtickets","params":[],"id":1}`, - unmarshalled: &NotifySpentAndMissedTicketsCmd{}, - }, { name: "notifynewtickets", newCmd: func() (interface{}, error) { diff --git a/rpc/jsonrpc/types/chainsvrwsntfns.go b/rpc/jsonrpc/types/chainsvrwsntfns.go index ab2b999417..94c325e87c 100644 --- a/rpc/jsonrpc/types/chainsvrwsntfns.go +++ b/rpc/jsonrpc/types/chainsvrwsntfns.go @@ -49,10 +49,6 @@ const ( // transaction was accepted by the mempool. RelevantTxAcceptedNtfnMethod Method = "relevanttxaccepted" - // SpentAndMissedTicketsNtfnMethod is the method of the daemon - // spentandmissedtickets notification. - SpentAndMissedTicketsNtfnMethod Method = "spentandmissedtickets" - // WinningTicketsNtfnMethod is the method of the daemon winningtickets // notification. WinningTicketsNtfnMethod Method = "winningtickets" @@ -154,25 +150,6 @@ func NewReorganizationNtfn(oldHash string, oldHeight int32, newHash string, } } -// SpentAndMissedTicketsNtfn is a type handling custom marshaling and -// unmarshaling of spentandmissedtickets JSON websocket notifications. -type SpentAndMissedTicketsNtfn struct { - Hash string - Height int32 - StakeDiff int64 - Tickets map[string]string -} - -// NewSpentAndMissedTicketsNtfn creates a new SpentAndMissedTicketsNtfn. -func NewSpentAndMissedTicketsNtfn(hash string, height int32, stakeDiff int64, tickets map[string]string) *SpentAndMissedTicketsNtfn { - return &SpentAndMissedTicketsNtfn{ - Hash: hash, - Height: height, - StakeDiff: stakeDiff, - Tickets: tickets, - } -} - // TxAcceptedNtfn defines the txaccepted JSON-RPC notification. type TxAcceptedNtfn struct { TxID string `json:"txid"` @@ -244,6 +221,5 @@ func init() { dcrjson.MustRegister(TxAcceptedNtfnMethod, (*TxAcceptedNtfn)(nil), flags) dcrjson.MustRegister(TxAcceptedVerboseNtfnMethod, (*TxAcceptedVerboseNtfn)(nil), flags) dcrjson.MustRegister(RelevantTxAcceptedNtfnMethod, (*RelevantTxAcceptedNtfn)(nil), flags) - dcrjson.MustRegister(SpentAndMissedTicketsNtfnMethod, (*SpentAndMissedTicketsNtfn)(nil), flags) dcrjson.MustRegister(WinningTicketsNtfnMethod, (*WinningTicketsNtfn)(nil), flags) } diff --git a/rpc/jsonrpc/types/chainsvrwsntfns_test.go b/rpc/jsonrpc/types/chainsvrwsntfns_test.go index c3d74006d4..2f1f23ab26 100644 --- a/rpc/jsonrpc/types/chainsvrwsntfns_test.go +++ b/rpc/jsonrpc/types/chainsvrwsntfns_test.go @@ -85,22 +85,6 @@ func TestChainSvrWsNtfns(t *testing.T) { Transaction: "001122", }, }, - { - name: "spentandmissedtickets", - newNtfn: func() (interface{}, error) { - return dcrjson.NewCmd(Method("spentandmissedtickets"), "123", 100, 3, map[string]string{"a": "b"}) - }, - staticNtfn: func() interface{} { - return NewSpentAndMissedTicketsNtfn("123", 100, 3, map[string]string{"a": "b"}) - }, - marshalled: `{"jsonrpc":"1.0","method":"spentandmissedtickets","params":["123",100,3,{"a":"b"}],"id":null}`, - unmarshalled: &SpentAndMissedTicketsNtfn{ - Hash: "123", - Height: 100, - StakeDiff: 3, - Tickets: map[string]string{"a": "b"}, - }, - }, { name: "txaccepted", newNtfn: func() (interface{}, error) { diff --git a/rpcclient/extensions.go b/rpcclient/extensions.go index 9b8641fbba..20d0549c7b 100644 --- a/rpcclient/extensions.go +++ b/rpcclient/extensions.go @@ -191,87 +191,6 @@ func (c *Client) ExistsAddresses(ctx context.Context, addresses []stdaddr.Addres return c.ExistsAddressesAsync(ctx, addresses).Receive() } -// FutureExistsMissedTicketsResult is a future promise to deliver the result of -// an ExistsMissedTicketsAsync RPC invocation (or an applicable error). -type FutureExistsMissedTicketsResult cmdRes - -// Receive waits for the response promised by the future and returns whether -// or not the tickets exist in the missed ticket database. -func (r *FutureExistsMissedTicketsResult) Receive() (string, error) { - res, err := receiveFuture(r.ctx, r.c) - if err != nil { - return "", err - } - - // Unmarshal the result as a string. - var exists string - err = json.Unmarshal(res, &exists) - if err != nil { - return "", err - } - return exists, nil -} - -// ExistsMissedTicketsAsync 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) ExistsMissedTicketsAsync(ctx context.Context, hashes []*chainhash.Hash) *FutureExistsMissedTicketsResult { - strHashes := make([]string, len(hashes)) - for i := range hashes { - strHashes[i] = hashes[i].String() - } - cmd := chainjson.NewExistsMissedTicketsCmd(strHashes) - return (*FutureExistsMissedTicketsResult)(c.sendCmd(ctx, cmd)) -} - -// ExistsMissedTickets returns a hex-encoded bitset describing whether or not -// ticket hashes exists in the missed ticket database. -func (c *Client) ExistsMissedTickets(ctx context.Context, hashes []*chainhash.Hash) (string, error) { - return c.ExistsMissedTicketsAsync(ctx, hashes).Receive() -} - -// FutureExistsExpiredTicketsResult is a future promise to deliver the result -// of a FutureExistsExpiredTicketsResultAsync RPC invocation (or an -// applicable error). -type FutureExistsExpiredTicketsResult cmdRes - -// Receive waits for the response promised by the future and returns whether -// or not the tickets exist in the expired ticket database. -func (r *FutureExistsExpiredTicketsResult) Receive() (string, error) { - res, err := receiveFuture(r.ctx, r.c) - if err != nil { - return "", err - } - - // Unmarshal the result as a string. - var exists string - err = json.Unmarshal(res, &exists) - if err != nil { - return "", err - } - return exists, nil -} - -// ExistsExpiredTicketsAsync 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) ExistsExpiredTicketsAsync(ctx context.Context, hashes []*chainhash.Hash) *FutureExistsExpiredTicketsResult { - strHashes := make([]string, len(hashes)) - for i := range hashes { - strHashes[i] = hashes[i].String() - } - cmd := chainjson.NewExistsExpiredTicketsCmd(strHashes) - return (*FutureExistsExpiredTicketsResult)(c.sendCmd(ctx, cmd)) -} - -// ExistsExpiredTickets returns information about whether or not a ticket hash exists -// in the expired ticket database. -// -// NOTE: This is a dcrd extension. -func (c *Client) ExistsExpiredTickets(ctx context.Context, hashes []*chainhash.Hash) (string, error) { - return c.ExistsExpiredTicketsAsync(ctx, hashes).Receive() -} - // FutureExistsLiveTicketResult is a future promise to deliver the result // of a FutureExistsLiveTicketResultAsync RPC invocation (or an // applicable error). @@ -790,53 +709,6 @@ func (c *Client) LiveTickets(ctx context.Context) ([]*chainhash.Hash, error) { return c.LiveTicketsAsync(ctx).Receive() } -// FutureMissedTicketsResult is a future promise to deliver the result -// of a FutureMissedTicketsResultAsync RPC invocation (or an applicable error). -type FutureMissedTicketsResult cmdRes - -// Receive waits for the response promised by the future and returns all -// currently missed tickets from the missed ticket database. -func (r *FutureMissedTicketsResult) Receive() ([]*chainhash.Hash, error) { - res, err := receiveFuture(r.ctx, r.c) - if err != nil { - return nil, err - } - - // Unmarshal result as a missed tickets result object. - var container chainjson.MissedTicketsResult - err = json.Unmarshal(res, &container) - if err != nil { - return nil, err - } - - missedTickets := make([]*chainhash.Hash, 0, len(container.Tickets)) - for _, ticketStr := range container.Tickets { - h, err := chainhash.NewHashFromStr(ticketStr) - if err != nil { - return nil, err - } - missedTickets = append(missedTickets, h) - } - - return missedTickets, nil -} - -// MissedTicketsAsync 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) MissedTicketsAsync(ctx context.Context) *FutureMissedTicketsResult { - cmd := chainjson.NewMissedTicketsCmd() - return (*FutureMissedTicketsResult)(c.sendCmd(ctx, cmd)) -} - -// MissedTickets returns all currently missed tickets from the missed -// ticket database in the daemon. -// -// NOTE: This is a dcrd extension. -func (c *Client) MissedTickets(ctx context.Context) ([]*chainhash.Hash, error) { - return c.MissedTicketsAsync(ctx).Receive() -} - // FutureSessionResult is a future promise to deliver the result of a // SessionAsync RPC invocation (or an applicable error). type FutureSessionResult cmdRes diff --git a/rpcclient/infrastructure.go b/rpcclient/infrastructure.go index d4219d509f..a4201f3bc2 100644 --- a/rpcclient/infrastructure.go +++ b/rpcclient/infrastructure.go @@ -279,9 +279,6 @@ func (c *Client) trackRegisteredNtfns(cmd interface{}) { case *chainjson.NotifyWinningTicketsCmd: c.ntfnState.notifyWinningTickets = true - case *chainjson.NotifySpentAndMissedTicketsCmd: - c.ntfnState.notifySpentAndMissedTickets = true - case *chainjson.NotifyNewTicketsCmd: c.ntfnState.notifyNewTickets = true @@ -586,14 +583,6 @@ func (c *Client) reregisterNtfns(ctx context.Context) error { } } - // Reregister notifyspendandmissedtickets if needed. - if stateCopy.notifySpentAndMissedTickets { - log.Debugf("Reregistering [notifyspentandmissedtickets]") - if err := c.NotifySpentAndMissedTickets(ctx); err != nil { - return err - } - } - // Reregister notifynewtickets if needed. if stateCopy.notifyNewTickets { log.Debugf("Reregistering [notifynewtickets]") diff --git a/rpcclient/notify.go b/rpcclient/notify.go index 41edd05d1d..22dfad5745 100644 --- a/rpcclient/notify.go +++ b/rpcclient/notify.go @@ -33,14 +33,13 @@ var ( // registered notifications so the state can be automatically re-established on // reconnect. type notificationState struct { - notifyBlocks bool - notifyWork bool - notifyTSpend bool - notifyWinningTickets bool - notifySpentAndMissedTickets bool - notifyNewTickets bool - notifyNewTx bool - notifyNewTxVerbose bool + notifyBlocks bool + notifyWork bool + notifyTSpend bool + notifyWinningTickets bool + notifyNewTickets bool + notifyNewTx bool + notifyNewTxVerbose bool } // Copy returns a deep copy of the receiver. @@ -50,7 +49,6 @@ func (s *notificationState) Copy() *notificationState { stateCopy.notifyWork = s.notifyWork stateCopy.notifyTSpend = s.notifyTSpend stateCopy.notifyWinningTickets = s.notifyWinningTickets - stateCopy.notifySpentAndMissedTickets = s.notifySpentAndMissedTickets stateCopy.notifyNewTickets = s.notifyNewTickets stateCopy.notifyNewTx = s.notifyNewTx stateCopy.notifyNewTxVerbose = s.notifyNewTxVerbose @@ -128,15 +126,6 @@ type NotificationHandlers struct { blockHeight int64, tickets []*chainhash.Hash) - // OnSpentAndMissedTickets is invoked when a block is connected to the - // longest (best) chain and tickets are spent or missed. It will only be - // invoked if a preceding call to NotifySpentAndMissedTickets has been made to - // register for the notification and the function is non-nil. - OnSpentAndMissedTickets func(hash *chainhash.Hash, - height int64, - stakeDiff int64, - tickets map[chainhash.Hash]bool) - // OnNewTickets is invoked when a block is connected to the longest (best) // chain and tickets have matured to become active. It will only be invoked // if a preceding call to NotifyNewTickets has been made to register for the @@ -298,27 +287,6 @@ func (c *Client) handleNotification(ntfn *rawNotification) { c.ntfnHandlers.OnWinningTickets(blockHash, blockHeight, tickets) - // OnSpentAndMissedTickets - case chainjson.SpentAndMissedTicketsNtfnMethod: - // Ignore the notification if the client is not interested in - // it. - if c.ntfnHandlers.OnSpentAndMissedTickets == nil { - return - } - - blockSha, blockHeight, stakeDifficulty, tickets, err := - parseSpentAndMissedTicketsNtfnParams(ntfn.Params) - if err != nil { - log.Warnf("Received invalid spend and missed tickets "+ - "notification: %v", err) - return - } - - c.ntfnHandlers.OnSpentAndMissedTickets(blockSha, - blockHeight, - stakeDifficulty, - tickets) - // OnNewTickets case chainjson.NewTicketsNtfnMethod: // Ignore the notification if the client is not interested in @@ -605,73 +573,6 @@ func parseWinningTicketsNtfnParams(params []json.RawMessage) ( return bHash, bHeight, t, nil } -// parseSpentAndMissedTicketsNtfnParams parses out the block header hash, height, -// winner number, and ticket map from a SpentAndMissedTickets notification. -func parseSpentAndMissedTicketsNtfnParams(params []json.RawMessage) ( - *chainhash.Hash, - int64, - int64, - map[chainhash.Hash]bool, - error) { - - if len(params) != 4 { - return nil, 0, 0, nil, wrongNumParams(len(params)) - } - - // Unmarshal first parameter as a string. - var blockShaStr string - err := json.Unmarshal(params[0], &blockShaStr) - if err != nil { - return nil, 0, 0, nil, err - } - - // Create ShaHash from block sha string. - sha, err := chainhash.NewHashFromStr(blockShaStr) - if err != nil { - return nil, 0, 0, nil, err - } - - // Unmarshal second parameter as an integer. - var blockHeight int32 - err = json.Unmarshal(params[1], &blockHeight) - if err != nil { - return nil, 0, 0, nil, err - } - bh := int64(blockHeight) - - // Unmarshal third parameter as an integer. - var stakeDiff int64 - err = json.Unmarshal(params[2], &stakeDiff) - if err != nil { - return nil, 0, 0, nil, err - } - - // Unmarshal fourth parameter as a map[*hash]bool. - tickets := make(map[string]string) - err = json.Unmarshal(params[3], &tickets) - if err != nil { - return nil, 0, 0, nil, err - } - t := make(map[chainhash.Hash]bool) - - for hashStr, spentStr := range tickets { - isSpent := false - if spentStr == "spent" { - isSpent = true - } - - // Create and cache ShaHash from tx hash. - ticketSha, err := chainhash.NewHashFromStr(hashStr) - if err != nil { - return nil, 0, 0, nil, err - } - - t[*ticketSha] = isSpent - } - - return sha, bh, stakeDiff, t, nil -} - // parseNewTicketsNtfnParams parses out the block header hash, height, // winner number, overflow, and ticket map from a NewTickets notification. func parseNewTicketsNtfnParams(params []json.RawMessage) (*chainhash.Hash, int64, int64, []*chainhash.Hash, error) { @@ -975,56 +876,6 @@ func (c *Client) NotifyWinningTickets(ctx context.Context) error { return c.NotifyWinningTicketsAsync(ctx).Receive() } -// FutureNotifySpentAndMissedTicketsResult is a future promise to deliver the result of a -// NotifySpentAndMissedTicketsAsync RPC invocation (or an applicable error). -type FutureNotifySpentAndMissedTicketsResult cmdRes - -// Receive waits for the response promised by the future and returns an error -// if the registration was not successful. -func (r *FutureNotifySpentAndMissedTicketsResult) Receive() error { - _, err := receiveFuture(r.ctx, r.c) - return err -} - -// NotifySpentAndMissedTicketsAsync 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 NotifySpentAndMissedTickets for the blocking version and more details. -// -// NOTE: This is a dcrd extension and requires a websocket connection. -func (c *Client) NotifySpentAndMissedTicketsAsync(ctx context.Context) *FutureNotifySpentAndMissedTicketsResult { - // Not supported in HTTP POST mode. - if c.config.HTTPPostMode { - return (*FutureNotifySpentAndMissedTicketsResult)(newFutureError(ctx, ErrWebsocketsRequired)) - } - - // Ignore the notification if the client is not interested in - // notifications. - if c.ntfnHandlers == nil { - return (*FutureNotifySpentAndMissedTicketsResult)(newNilFutureResult(ctx)) - } - - cmd := chainjson.NewNotifySpentAndMissedTicketsCmd() - - return (*FutureNotifySpentAndMissedTicketsResult)(c.sendCmd(ctx, cmd)) -} - -// NotifySpentAndMissedTickets registers the client to receive notifications when -// blocks are connected to the main chain and tickets are spent or missed. The -// notifications are delivered to the notification handlers associated with the -// client. Calling this function has no effect if there are no notification -// handlers and will result in an error if the client is configured to run in HTTP -// POST mode. -// -// The notifications delivered as a result of this call will be those from -// OnSpentAndMissedTickets. -// -// NOTE: This is a dcrd extension and requires a websocket connection. -func (c *Client) NotifySpentAndMissedTickets(ctx context.Context) error { - return c.NotifySpentAndMissedTicketsAsync(ctx).Receive() -} - // FutureNotifyNewTicketsResult is a future promise to deliver the result of a // NotifyNewTicketsAsync RPC invocation (or an applicable error). type FutureNotifyNewTicketsResult cmdRes diff --git a/server.go b/server.go index 04fbdb8a5d..d7a57a9ee9 100644 --- a/server.go +++ b/server.go @@ -2787,22 +2787,6 @@ func (s *server) handleBlockchainNotification(notification *blockchain.Notificat // guaranteed to no longer be useful. s.proactivelyEvictSigCacheEntries(block.Height()) - // Stake tickets are spent or missed from the most recently connected block. - case blockchain.NTSpentAndMissedTickets: - // WARNING: The chain lock is not released before sending this - // notification, so care must be taken to avoid calling chain functions - // which could result in a deadlock. - tnd, ok := notification.Data.(*blockchain.TicketNotificationsData) - if !ok { - syncLog.Warnf("Tickets connected notification is not " + - "TicketNotificationsData") - break - } - - if r := s.rpcServer; r != nil { - r.NotifySpentAndMissedTickets(tnd) - } - // Stake tickets are matured from the most recently connected block. case blockchain.NTNewTickets: // WARNING: The chain lock is not released before sending this