/
notifications.go
102 lines (94 loc) · 2.99 KB
/
notifications.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright (c) 2019 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package dcrd
import (
"encoding/json"
"github.com/Decred-Next/dcrnd/chaincfg/chainhash/v8"
"github.com/Decred-Next/dcrnd/wire/v8"
"github.com/Decred-Next/dcrnwallet/errors/version2/v8"
)
func unmarshalArray(j json.RawMessage, params ...interface{}) error {
err := json.Unmarshal(j, ¶ms)
if err != nil {
return errors.E(errors.Encoding, err)
}
return nil
}
// WinningTickets extracts the parameters from a winningtickets JSON-RPC
// notification.
func WinningTickets(params json.RawMessage) (block *chainhash.Hash, height int32, winners []*chainhash.Hash, err error) {
// Parameters (array):
// 0: block hash (reversed hex string)
// 1: block height (number)
// 2: object with ticket hashes in values
ticketObj := make(map[string]*hash)
hash := new(hash)
err = unmarshalArray(params, hash, &height, &ticketObj)
if err != nil {
return
}
winners = make([]*chainhash.Hash, 0, len(ticketObj))
for _, h := range ticketObj {
winners = append(winners, h.Hash)
}
return hash.Hash, height, winners, nil
}
// BlockConnected extracts the parameters from a blockconnected JSON-RPC
// notification.
func BlockConnected(params json.RawMessage) (header *wire.BlockHeader, relevant []*wire.MsgTx, err error) {
// Parameters (array):
// 0: block header
// 1: array of relevant hex-encoded transactions
header = new(wire.BlockHeader)
txs := new(transactions)
err = unmarshalArray(params, unhex(header), txs)
if err != nil {
return
}
return header, txs.Transactions, nil
}
// RelevantTxAccepted extracts the parameters from a relevanttxaccepted JSON-RPC
// notification.
func RelevantTxAccepted(params json.RawMessage) (tx *wire.MsgTx, err error) {
// Parameters (array):
// 0: relevant hex-encoded transaction
tx = new(wire.MsgTx)
err = unmarshalArray(params, unhex(tx))
return
}
// MissedTickets extracts the missed ticket hashes from the parameters of a
// spentandmissedtickets JSON-RPC notification.
func MissedTickets(params json.RawMessage) (missed []*chainhash.Hash, err error) {
// Parameters (array):
// 0: Block hash (reversed hex)
// 1: Block height (numeric)
// 2: Stake difficulty (numeric)
// 3: Object of tickets (keyed by ticket hash, value is "missed" or "spent")
//
// Of these, we only need the hashes of missed tickets.
var paramArray []json.RawMessage
err = json.Unmarshal(params, ¶mArray)
if err != nil {
return nil, errors.E(errors.Encoding, err)
}
if len(paramArray) < 4 {
return nil, errors.E(errors.Protocol, "missing notification parameters")
}
ticketObj := make(map[string]string)
err = json.Unmarshal(paramArray[3], &ticketObj)
if err != nil {
return nil, errors.E(errors.Encoding, err)
}
for k, v := range ticketObj {
if v != "missed" {
continue
}
hash, err := chainhash.NewHashFromStr(k)
if err != nil {
return nil, errors.E(errors.Encoding, err)
}
missed = append(missed, hash)
}
return missed, nil
}